summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Everton <dan@iocaine.org>2007-08-08 10:19:56 +0000
committerDan Everton <dan@iocaine.org>2007-08-08 10:19:56 +0000
commiteecfe9f1cb85b53b59d2487e0ae4c05bf43a8bd3 (patch)
tree9ec358e6b12735468c63eebaaa02da9a7b5d0f65
parentecae04a9f27f6694e748bbde5d49fbd47a01fec3 (diff)
downloadrockbox-eecfe9f1cb85b53b59d2487e0ae4c05bf43a8bd3.tar.gz
rockbox-eecfe9f1cb85b53b59d2487e0ae4c05bf43a8bd3.zip
Add support for grouping tags. From FS#7362.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14242 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/gui/gwps-common.c3
-rw-r--r--apps/gui/gwps.h1
-rw-r--r--apps/gui/wps_debug.c5
-rw-r--r--apps/gui/wps_parser.c2
-rw-r--r--apps/lang/deutsch.lang14
-rw-r--r--apps/lang/english.lang14
-rw-r--r--apps/metadata/metadata_common.c12
-rw-r--r--apps/metadata/mp4.c6
-rw-r--r--apps/screens.c30
-rw-r--r--apps/tagcache.c28
-rw-r--r--apps/tagcache.h6
-rw-r--r--apps/tagtree.c1
-rw-r--r--docs/CREDITS1
-rw-r--r--firmware/export/id3.h1
-rw-r--r--firmware/id3.c6
15 files changed, 109 insertions, 21 deletions
diff --git a/apps/gui/gwps-common.c b/apps/gui/gwps-common.c
index 82bf7541f2..3c74509ec8 100644
--- a/apps/gui/gwps-common.c
+++ b/apps/gui/gwps-common.c
@@ -866,6 +866,9 @@ static char *get_token_value(struct gui_wps *gwps,
866 case WPS_TOKEN_METADATA_ALBUM_ARTIST: 866 case WPS_TOKEN_METADATA_ALBUM_ARTIST:
867 return id3->albumartist; 867 return id3->albumartist;
868 868
869 case WPS_TOKEN_METADATA_GROUPING:
870 return id3->grouping;
871
869 case WPS_TOKEN_METADATA_GENRE: 872 case WPS_TOKEN_METADATA_GENRE:
870 return id3->genre_string; 873 return id3->genre_string;
871 874
diff --git a/apps/gui/gwps.h b/apps/gui/gwps.h
index b02b87f2c9..83ff14b80b 100644
--- a/apps/gui/gwps.h
+++ b/apps/gui/gwps.h
@@ -191,6 +191,7 @@ enum wps_token_type {
191 WPS_TOKEN_METADATA_ARTIST, 191 WPS_TOKEN_METADATA_ARTIST,
192 WPS_TOKEN_METADATA_COMPOSER, 192 WPS_TOKEN_METADATA_COMPOSER,
193 WPS_TOKEN_METADATA_ALBUM_ARTIST, 193 WPS_TOKEN_METADATA_ALBUM_ARTIST,
194 WPS_TOKEN_METADATA_GROUPING,
194 WPS_TOKEN_METADATA_ALBUM, 195 WPS_TOKEN_METADATA_ALBUM,
195 WPS_TOKEN_METADATA_GENRE, 196 WPS_TOKEN_METADATA_GENRE,
196 WPS_TOKEN_METADATA_DISC_NUMBER, 197 WPS_TOKEN_METADATA_DISC_NUMBER,
diff --git a/apps/gui/wps_debug.c b/apps/gui/wps_debug.c
index 50ffcce119..58e6ab49aa 100644
--- a/apps/gui/wps_debug.c
+++ b/apps/gui/wps_debug.c
@@ -289,6 +289,11 @@ static void dump_wps_tokens(struct wps_data *data)
289 next_str(next)); 289 next_str(next));
290 break; 290 break;
291 291
292 case WPS_TOKEN_METADATA_GROUPING:
293 snprintf(buf, sizeof(buf), "%strack grouping",
294 next_str(next));
295 break;
296
292 case WPS_TOKEN_METADATA_GENRE: 297 case WPS_TOKEN_METADATA_GENRE:
293 snprintf(buf, sizeof(buf), "%strack genre", 298 snprintf(buf, sizeof(buf), "%strack genre",
294 next_str(next)); 299 next_str(next));
diff --git a/apps/gui/wps_parser.c b/apps/gui/wps_parser.c
index d66e47dfe7..8471bff7d8 100644
--- a/apps/gui/wps_parser.c
+++ b/apps/gui/wps_parser.c
@@ -200,6 +200,7 @@ static const struct wps_tag all_tags[] = {
200 { WPS_TOKEN_METADATA_COMPOSER, "ic", WPS_REFRESH_STATIC, NULL }, 200 { WPS_TOKEN_METADATA_COMPOSER, "ic", WPS_REFRESH_STATIC, NULL },
201 { WPS_TOKEN_METADATA_ALBUM, "id", WPS_REFRESH_STATIC, NULL }, 201 { WPS_TOKEN_METADATA_ALBUM, "id", WPS_REFRESH_STATIC, NULL },
202 { WPS_TOKEN_METADATA_ALBUM_ARTIST, "iA", WPS_REFRESH_STATIC, NULL }, 202 { WPS_TOKEN_METADATA_ALBUM_ARTIST, "iA", WPS_REFRESH_STATIC, NULL },
203 { WPS_TOKEN_METADATA_GROUPING, "iG", WPS_REFRESH_STATIC, NULL },
203 { WPS_TOKEN_METADATA_GENRE, "ig", WPS_REFRESH_STATIC, NULL }, 204 { WPS_TOKEN_METADATA_GENRE, "ig", WPS_REFRESH_STATIC, NULL },
204 { WPS_TOKEN_METADATA_DISC_NUMBER, "ik", WPS_REFRESH_STATIC, NULL }, 205 { WPS_TOKEN_METADATA_DISC_NUMBER, "ik", WPS_REFRESH_STATIC, NULL },
205 { WPS_TOKEN_METADATA_TRACK_NUMBER, "in", WPS_REFRESH_STATIC, NULL }, 206 { WPS_TOKEN_METADATA_TRACK_NUMBER, "in", WPS_REFRESH_STATIC, NULL },
@@ -213,6 +214,7 @@ static const struct wps_tag all_tags[] = {
213 { WPS_TOKEN_METADATA_COMPOSER, "Ic", WPS_REFRESH_DYNAMIC, NULL }, 214 { WPS_TOKEN_METADATA_COMPOSER, "Ic", WPS_REFRESH_DYNAMIC, NULL },
214 { WPS_TOKEN_METADATA_ALBUM, "Id", WPS_REFRESH_DYNAMIC, NULL }, 215 { WPS_TOKEN_METADATA_ALBUM, "Id", WPS_REFRESH_DYNAMIC, NULL },
215 { WPS_TOKEN_METADATA_ALBUM_ARTIST, "IA", WPS_REFRESH_DYNAMIC, NULL }, 216 { WPS_TOKEN_METADATA_ALBUM_ARTIST, "IA", WPS_REFRESH_DYNAMIC, NULL },
217 { WPS_TOKEN_METADATA_GROUPING, "IG", WPS_REFRESH_DYNAMIC, NULL },
216 { WPS_TOKEN_METADATA_GENRE, "Ig", WPS_REFRESH_DYNAMIC, NULL }, 218 { WPS_TOKEN_METADATA_GENRE, "Ig", WPS_REFRESH_DYNAMIC, NULL },
217 { WPS_TOKEN_METADATA_DISC_NUMBER, "Ik", WPS_REFRESH_DYNAMIC, NULL }, 219 { WPS_TOKEN_METADATA_DISC_NUMBER, "Ik", WPS_REFRESH_DYNAMIC, NULL },
218 { WPS_TOKEN_METADATA_TRACK_NUMBER, "In", WPS_REFRESH_DYNAMIC, NULL }, 220 { WPS_TOKEN_METADATA_TRACK_NUMBER, "In", WPS_REFRESH_DYNAMIC, NULL },
diff --git a/apps/lang/deutsch.lang b/apps/lang/deutsch.lang
index a50d021c4e..51ff6e454f 100644
--- a/apps/lang/deutsch.lang
+++ b/apps/lang/deutsch.lang
@@ -11017,3 +11017,17 @@
11017 *: "Als Aufnahmeverzeichnis festlegen" 11017 *: "Als Aufnahmeverzeichnis festlegen"
11018 </voice> 11018 </voice>
11019</phrase> 11019</phrase>
11020<phrase>
11021 id: LANG_ID3_GROUPING
11022 desc: in tag viewer
11023 user:
11024 <source>
11025 *: "[Work]"
11026 </source>
11027 <dest>
11028 *: "[Werk]"
11029 </dest>
11030 <voice>
11031 *: ""
11032 </voice>
11033</phrase>
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 6f631282f7..4fd4ecf54d 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -11004,3 +11004,17 @@
11004 *: "Demos" 11004 *: "Demos"
11005 </voice> 11005 </voice>
11006</phrase> 11006</phrase>
11007<phrase>
11008 id: LANG_ID3_GROUPING
11009 desc: in tag viewer
11010 user:
11011 <source>
11012 *: "[Work]"
11013 </source>
11014 <dest>
11015 *: "[Work]"
11016 </dest>
11017 <voice>
11018 *: ""
11019 </voice>
11020</phrase>
diff --git a/apps/metadata/metadata_common.c b/apps/metadata/metadata_common.c
index d1a1087188..e3579473f0 100644
--- a/apps/metadata/metadata_common.c
+++ b/apps/metadata/metadata_common.c
@@ -280,6 +280,18 @@ long parse_tag(const char* name, char* value, struct mp3entry* id3,
280 { 280 {
281 p = &(id3->albumartist); 281 p = &(id3->albumartist);
282 } 282 }
283 else if (strcasecmp(name, "grouping") == 0)
284 {
285 p = &(id3->grouping);
286 }
287 else if (strcasecmp(name, "content group") == 0)
288 {
289 p = &(id3->grouping);
290 }
291 else if (strcasecmp(name, "contentgroup") == 0)
292 {
293 p = &(id3->grouping);
294 }
283 else 295 else
284 { 296 {
285 len = parse_replaygain(name, value, id3, buf, buf_remaining); 297 len = parse_replaygain(name, value, id3, buf, buf_remaining);
diff --git a/apps/metadata/mp4.c b/apps/metadata/mp4.c
index aecb4cf17f..8162cd987f 100644
--- a/apps/metadata/mp4.c
+++ b/apps/metadata/mp4.c
@@ -38,6 +38,7 @@
38#define MP4_alac MP4_ID('a', 'l', 'a', 'c') 38#define MP4_alac MP4_ID('a', 'l', 'a', 'c')
39#define MP4_calb MP4_ID(0xa9, 'a', 'l', 'b') 39#define MP4_calb MP4_ID(0xa9, 'a', 'l', 'b')
40#define MP4_cART MP4_ID(0xa9, 'A', 'R', 'T') 40#define MP4_cART MP4_ID(0xa9, 'A', 'R', 'T')
41#define MP4_cgrp MP4_ID(0xa9, 'g', 'r', 'p')
41#define MP4_cgen MP4_ID(0xa9, 'g', 'e', 'n') 42#define MP4_cgen MP4_ID(0xa9, 'g', 'e', 'n')
42#define MP4_cnam MP4_ID(0xa9, 'n', 'a', 'm') 43#define MP4_cnam MP4_ID(0xa9, 'n', 'a', 'm')
43#define MP4_cwrt MP4_ID(0xa9, 'w', 'r', 't') 44#define MP4_cwrt MP4_ID(0xa9, 'w', 'r', 't')
@@ -378,6 +379,11 @@ static bool read_mp4_tags(int fd, struct mp3entry* id3,
378 &id3->albumartist); 379 &id3->albumartist);
379 break; 380 break;
380 381
382 case MP4_cgrp:
383 read_mp4_tag_string(fd, size, &buffer, &buffer_left,
384 &id3->grouping);
385 break;
386
381 case MP4_calb: 387 case MP4_calb:
382 read_mp4_tag_string(fd, size, &buffer, &buffer_left, 388 read_mp4_tag_string(fd, size, &buffer, &buffer_left,
383 &id3->album); 389 &id3->album);
diff --git a/apps/screens.c b/apps/screens.c
index 1f0939ab8d..b74347405e 100644
--- a/apps/screens.c
+++ b/apps/screens.c
@@ -1151,6 +1151,7 @@ static const int id3_headers[]=
1151 LANG_ID3_ARTIST, 1151 LANG_ID3_ARTIST,
1152 LANG_ID3_ALBUM, 1152 LANG_ID3_ALBUM,
1153 LANG_ID3_ALBUMARTIST, 1153 LANG_ID3_ALBUMARTIST,
1154 LANG_ID3_GROUPING,
1154 LANG_ID3_DISCNUM, 1155 LANG_ID3_DISCNUM,
1155 LANG_ID3_TRACKNUM, 1156 LANG_ID3_TRACKNUM,
1156 LANG_ID3_COMMENT, 1157 LANG_ID3_COMMENT,
@@ -1193,7 +1194,10 @@ static char * id3_get_info(int selected_item, void* data, char *buffer)
1193 case 3:/*LANG_ID3_ALBUMARTIST*/ 1194 case 3:/*LANG_ID3_ALBUMARTIST*/
1194 info=id3->albumartist; 1195 info=id3->albumartist;
1195 break; 1196 break;
1196 case 4:/*LANG_ID3_DISCNUM*/ 1197 case 4:/*LANG_ID3_ALBUMARTIST*/
1198 info=id3->grouping;
1199 break;
1200 case 5:/*LANG_ID3_DISCNUM*/
1197 if (id3->disc_string) 1201 if (id3->disc_string)
1198 info = id3->disc_string; 1202 info = id3->disc_string;
1199 else if (id3->discnum) 1203 else if (id3->discnum)
@@ -1202,7 +1206,7 @@ static char * id3_get_info(int selected_item, void* data, char *buffer)
1202 info = buffer; 1206 info = buffer;
1203 } 1207 }
1204 break; 1208 break;
1205 case 5:/*LANG_ID3_TRACKNUM*/ 1209 case 6:/*LANG_ID3_TRACKNUM*/
1206 if (id3->track_string) 1210 if (id3->track_string)
1207 info = id3->track_string; 1211 info = id3->track_string;
1208 else if (id3->tracknum) 1212 else if (id3->tracknum)
@@ -1211,13 +1215,13 @@ static char * id3_get_info(int selected_item, void* data, char *buffer)
1211 info = buffer; 1215 info = buffer;
1212 } 1216 }
1213 break; 1217 break;
1214 case 6:/*LANG_ID3_COMMENT*/ 1218 case 7:/*LANG_ID3_COMMENT*/
1215 info=id3->comment; 1219 info=id3->comment;
1216 break; 1220 break;
1217 case 7:/*LANG_ID3_GENRE*/ 1221 case 8:/*LANG_ID3_GENRE*/
1218 info = id3->genre_string; 1222 info = id3->genre_string;
1219 break; 1223 break;
1220 case 8:/*LANG_ID3_YEAR*/ 1224 case 9:/*LANG_ID3_YEAR*/
1221 if (id3->year_string) 1225 if (id3->year_string)
1222 info = id3->year_string; 1226 info = id3->year_string;
1223 else if (id3->year) 1227 else if (id3->year)
@@ -1226,34 +1230,34 @@ static char * id3_get_info(int selected_item, void* data, char *buffer)
1226 info = buffer; 1230 info = buffer;
1227 } 1231 }
1228 break; 1232 break;
1229 case 9:/*LANG_ID3_LENGTH*/ 1233 case 10:/*LANG_ID3_LENGTH*/
1230 format_time(buffer, MAX_PATH, id3->length); 1234 format_time(buffer, MAX_PATH, id3->length);
1231 info=buffer; 1235 info=buffer;
1232 break; 1236 break;
1233 case 10:/*LANG_ID3_PLAYLIST*/ 1237 case 11:/*LANG_ID3_PLAYLIST*/
1234 snprintf(buffer, MAX_PATH, "%d/%d", playlist_get_display_index(), 1238 snprintf(buffer, MAX_PATH, "%d/%d", playlist_get_display_index(),
1235 playlist_amount()); 1239 playlist_amount());
1236 info=buffer; 1240 info=buffer;
1237 break; 1241 break;
1238 case 11:/*LANG_ID3_BITRATE*/ 1242 case 12:/*LANG_ID3_BITRATE*/
1239 snprintf(buffer, MAX_PATH, "%d kbps%s", id3->bitrate, 1243 snprintf(buffer, MAX_PATH, "%d kbps%s", id3->bitrate,
1240 id3->vbr ? str(LANG_ID3_VBR) : (const unsigned char*) ""); 1244 id3->vbr ? str(LANG_ID3_VBR) : (const unsigned char*) "");
1241 info=buffer; 1245 info=buffer;
1242 break; 1246 break;
1243 case 12:/*LANG_ID3_FREQUENCY*/ 1247 case 13:/*LANG_ID3_FREQUENCY*/
1244 snprintf(buffer, MAX_PATH, "%ld Hz", id3->frequency); 1248 snprintf(buffer, MAX_PATH, "%ld Hz", id3->frequency);
1245 info=buffer; 1249 info=buffer;
1246 break; 1250 break;
1247#if CONFIG_CODEC == SWCODEC 1251#if CONFIG_CODEC == SWCODEC
1248 case 13:/*LANG_ID3_TRACK_GAIN*/ 1252 case 14:/*LANG_ID3_TRACK_GAIN*/
1249 info=id3->track_gain_string; 1253 info=id3->track_gain_string;
1250 break; 1254 break;
1251 case 14:/*LANG_ID3_ALBUM_GAIN*/ 1255 case 15:/*LANG_ID3_ALBUM_GAIN*/
1252 info=id3->album_gain_string; 1256 info=id3->album_gain_string;
1253 break; 1257 break;
1254 case 15:/*LANG_ID3_PATH*/ 1258 case 16:/*LANG_ID3_PATH*/
1255#else 1259#else
1256 case 13:/*LANG_ID3_PATH*/ 1260 case 17:/*LANG_ID3_PATH*/
1257#endif 1261#endif
1258 info=id3->path; 1262 info=id3->path;
1259 break; 1263 break;
diff --git a/apps/tagcache.c b/apps/tagcache.c
index da51e0c4e9..309718a932 100644
--- a/apps/tagcache.c
+++ b/apps/tagcache.c
@@ -108,11 +108,11 @@ static long tempbuf_pos;
108 108
109/* Tags we want to get sorted (loaded to the tempbuf). */ 109/* Tags we want to get sorted (loaded to the tempbuf). */
110static const int sorted_tags[] = { tag_artist, tag_album, tag_genre, 110static const int sorted_tags[] = { tag_artist, tag_album, tag_genre,
111 tag_composer, tag_comment, tag_albumartist, tag_title }; 111 tag_composer, tag_comment, tag_albumartist, tag_grouping, tag_title };
112 112
113/* Uniqued tags (we can use these tags with filters and conditional clauses). */ 113/* Uniqued tags (we can use these tags with filters and conditional clauses). */
114static const int unique_tags[] = { tag_artist, tag_album, tag_genre, 114static const int unique_tags[] = { tag_artist, tag_album, tag_genre,
115 tag_composer, tag_comment, tag_albumartist }; 115 tag_composer, tag_comment, tag_albumartist, tag_grouping };
116 116
117/* Numeric tags (we can use these tags with conditional clauses). */ 117/* Numeric tags (we can use these tags with conditional clauses). */
118static const int numeric_tags[] = { tag_year, tag_discnumber, tag_tracknumber, tag_length, 118static 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
123 123
124/* String presentation of the tags defined in tagcache.h. Must be in correct order! */ 124/* String presentation of the tags defined in tagcache.h. Must be in correct order! */
125static const char *tags_str[] = { "artist", "album", "genre", "title", 125static const char *tags_str[] = { "artist", "album", "genre", "title",
126 "filename", "composer", "comment", "albumartist", "year", "discnumber", "tracknumber", 126 "filename", "composer", "comment", "albumartist", "grouping", "year", "discnumber", "tracknumber",
127 "bitrate", "length", "playcount", "rating", "playtime", "lastplayed", "commitid" }; 127 "bitrate", "length", "playcount", "rating", "playtime", "lastplayed", "commitid" };
128 128
129/* Status information of the tagcache. */ 129/* Status information of the tagcache. */
@@ -188,7 +188,7 @@ struct master_header {
188 188
189/* For the endianess correction */ 189/* For the endianess correction */
190static const char *tagfile_entry_ec = "ss"; 190static const char *tagfile_entry_ec = "ss";
191static const char *index_entry_ec = "lllllllllllllllllll"; /* (1 + TAG_COUNT) * l */ 191static const char *index_entry_ec = "llllllllllllllllllll"; /* (1 + TAG_COUNT) * l */
192static const char *tagcache_header_ec = "lll"; 192static const char *tagcache_header_ec = "lll";
193static const char *master_header_ec = "llllll"; 193static const char *master_header_ec = "llllll";
194 194
@@ -1549,6 +1549,7 @@ bool tagcache_fill_tags(struct mp3entry *id3, const char *filename)
1549 id3->composer = get_tag_string(entry, tag_composer); 1549 id3->composer = get_tag_string(entry, tag_composer);
1550 id3->comment = get_tag_string(entry, tag_comment); 1550 id3->comment = get_tag_string(entry, tag_comment);
1551 id3->albumartist = get_tag_string(entry, tag_albumartist); 1551 id3->albumartist = get_tag_string(entry, tag_albumartist);
1552 id3->grouping = get_tag_string(entry, tag_grouping);
1552 1553
1553 id3->playcount = get_tag_numeric(entry, tag_playcount); 1554 id3->playcount = get_tag_numeric(entry, tag_playcount);
1554 id3->rating = get_tag_numeric(entry, tag_rating); 1555 id3->rating = get_tag_numeric(entry, tag_rating);
@@ -1615,6 +1616,7 @@ static void add_tagcache(char *path)
1615 int offset = 0; 1616 int offset = 0;
1616 int path_length = strlen(path); 1617 int path_length = strlen(path);
1617 bool has_albumartist; 1618 bool has_albumartist;
1619 bool has_grouping;
1618 1620
1619 if (cachefd < 0) 1621 if (cachefd < 0)
1620 return ; 1622 return ;
@@ -1708,6 +1710,8 @@ static void add_tagcache(char *path)
1708 /* String tags. */ 1710 /* String tags. */
1709 has_albumartist = track.id3.albumartist != NULL 1711 has_albumartist = track.id3.albumartist != NULL
1710 && strlen(track.id3.albumartist) > 0; 1712 && strlen(track.id3.albumartist) > 0;
1713 has_grouping = track.id3.grouping != NULL
1714 && strlen(track.id3.grouping) > 0;
1711 1715
1712 ADD_TAG(entry, tag_filename, &path); 1716 ADD_TAG(entry, tag_filename, &path);
1713 ADD_TAG(entry, tag_title, &track.id3.title); 1717 ADD_TAG(entry, tag_title, &track.id3.title);
@@ -1724,6 +1728,14 @@ static void add_tagcache(char *path)
1724 { 1728 {
1725 ADD_TAG(entry, tag_albumartist, &track.id3.artist); 1729 ADD_TAG(entry, tag_albumartist, &track.id3.artist);
1726 } 1730 }
1731 if (has_grouping)
1732 {
1733 ADD_TAG(entry, tag_grouping, &track.id3.grouping);
1734 }
1735 else
1736 {
1737 ADD_TAG(entry, tag_grouping, &track.id3.title);
1738 }
1727 entry.data_length = offset; 1739 entry.data_length = offset;
1728 1740
1729 /* Write the header */ 1741 /* Write the header */
@@ -1745,6 +1757,14 @@ static void add_tagcache(char *path)
1745 { 1757 {
1746 write_item(track.id3.artist); 1758 write_item(track.id3.artist);
1747 } 1759 }
1760 if (has_grouping)
1761 {
1762 write_item(track.id3.grouping);
1763 }
1764 else
1765 {
1766 write_item(track.id3.title);
1767 }
1748 total_entry_count++; 1768 total_entry_count++;
1749} 1769}
1750 1770
diff --git a/apps/tagcache.h b/apps/tagcache.h
index ada624783a..118b4c4119 100644
--- a/apps/tagcache.h
+++ b/apps/tagcache.h
@@ -23,7 +23,7 @@
23#include "id3.h" 23#include "id3.h"
24 24
25enum tag_type { tag_artist = 0, tag_album, tag_genre, tag_title, 25enum tag_type { tag_artist = 0, tag_album, tag_genre, tag_title,
26 tag_filename, tag_composer, tag_comment, tag_albumartist, tag_year, 26 tag_filename, tag_composer, tag_comment, tag_albumartist, tag_grouping, tag_year,
27 tag_discnumber, tag_tracknumber, tag_bitrate, tag_length, tag_playcount, tag_rating, 27 tag_discnumber, tag_tracknumber, tag_bitrate, tag_length, tag_playcount, tag_rating,
28 tag_playtime, tag_lastplayed, tag_commitid, 28 tag_playtime, tag_lastplayed, tag_commitid,
29 /* Virtual tags */ 29 /* Virtual tags */
@@ -31,7 +31,7 @@ enum tag_type { tag_artist = 0, tag_album, tag_genre, tag_title,
31 tag_virt_playtime_min, tag_virt_playtime_sec, 31 tag_virt_playtime_min, tag_virt_playtime_sec,
32 tag_virt_entryage, tag_virt_autoscore }; 32 tag_virt_entryage, tag_virt_autoscore };
33 33
34#define TAG_COUNT 18 34#define TAG_COUNT 19
35 35
36/* Maximum length of a single tag. */ 36/* Maximum length of a single tag. */
37#define TAG_MAXLEN (MAX_PATH*2) 37#define TAG_MAXLEN (MAX_PATH*2)
@@ -43,7 +43,7 @@ enum tag_type { tag_artist = 0, tag_album, tag_genre, tag_title,
43#define IDX_BUF_DEPTH 64 43#define IDX_BUF_DEPTH 64
44 44
45/* Tag Cache Header version 'TCHxx'. Increment when changing internal structures. */ 45/* Tag Cache Header version 'TCHxx'. Increment when changing internal structures. */
46#define TAGCACHE_MAGIC 0x5443480A 46#define TAGCACHE_MAGIC 0x5443480b
47 47
48/* How much to allocate extra space for ramcache. */ 48/* How much to allocate extra space for ramcache. */
49#define TAGCACHE_RESERVE 32768 49#define TAGCACHE_RESERVE 32768
diff --git a/apps/tagtree.c b/apps/tagtree.c
index 59fb8c131f..f9ae0bebd3 100644
--- a/apps/tagtree.c
+++ b/apps/tagtree.c
@@ -200,6 +200,7 @@ static int get_tag(int *tag)
200 MATCH(tag, buf, "comment", tag_comment); 200 MATCH(tag, buf, "comment", tag_comment);
201 MATCH(tag, buf, "albumartist", tag_albumartist); 201 MATCH(tag, buf, "albumartist", tag_albumartist);
202 MATCH(tag, buf, "ensemble", tag_albumartist); 202 MATCH(tag, buf, "ensemble", tag_albumartist);
203 MATCH(tag, buf, "grouping", tag_grouping);
203 MATCH(tag, buf, "genre", tag_genre); 204 MATCH(tag, buf, "genre", tag_genre);
204 MATCH(tag, buf, "length", tag_length); 205 MATCH(tag, buf, "length", tag_length);
205 MATCH(tag, buf, "Lm", tag_virt_length_min); 206 MATCH(tag, buf, "Lm", tag_virt_length_min);
diff --git a/docs/CREDITS b/docs/CREDITS
index 84d8d9f528..4dbc2dfd84 100644
--- a/docs/CREDITS
+++ b/docs/CREDITS
@@ -311,6 +311,7 @@ Tobias Schladt
311John Zhou 311John Zhou
312Charles Voelger 312Charles Voelger
313Gerritt Gonzales 313Gerritt Gonzales
314Dieter Pellkofer
314The libmad team 315The libmad team
315The wavpack team 316The wavpack team
316The ffmpeg team 317The ffmpeg team
diff --git a/firmware/export/id3.h b/firmware/export/id3.h
index 8c91456040..2751fde6f5 100644
--- a/firmware/export/id3.h
+++ b/firmware/export/id3.h
@@ -153,6 +153,7 @@ struct mp3entry {
153 char* composer; 153 char* composer;
154 char* comment; 154 char* comment;
155 char* albumartist; 155 char* albumartist;
156 char* grouping;
156 int discnum; 157 int discnum;
157 int tracknum; 158 int tracknum;
158 int version; 159 int version;
diff --git a/firmware/id3.c b/firmware/id3.c
index a66318b2fc..851aa83a5a 100644
--- a/firmware/id3.c
+++ b/firmware/id3.c
@@ -460,7 +460,9 @@ static const struct tag_resolver taglist[] = {
460 { "TYE", 3, offsetof(struct mp3entry, year_string), &parseyearnum, false }, 460 { "TYE", 3, offsetof(struct mp3entry, year_string), &parseyearnum, false },
461 { "TCOM", 4, offsetof(struct mp3entry, composer), NULL, false }, 461 { "TCOM", 4, offsetof(struct mp3entry, composer), NULL, false },
462 { "TPE2", 4, offsetof(struct mp3entry, albumartist), NULL, false }, 462 { "TPE2", 4, offsetof(struct mp3entry, albumartist), NULL, false },
463 { "TP2", 3, offsetof(struct mp3entry, albumartist), NULL, false }, 463 { "TP2", 3, offsetof(struct mp3entry, albumartist), NULL, false },
464 { "TIT1", 4, offsetof(struct mp3entry, grouping), NULL, false },
465 { "TT1", 3, offsetof(struct mp3entry, grouping), NULL, false },
464 { "COMM", 4, offsetof(struct mp3entry, comment), NULL, false }, 466 { "COMM", 4, offsetof(struct mp3entry, comment), NULL, false },
465 { "TCON", 4, offsetof(struct mp3entry, genre_string), &parsegenre, false }, 467 { "TCON", 4, offsetof(struct mp3entry, genre_string), &parsegenre, false },
466 { "TCO", 3, offsetof(struct mp3entry, genre_string), &parsegenre, false }, 468 { "TCO", 3, offsetof(struct mp3entry, genre_string), &parsegenre, false },
@@ -1192,6 +1194,8 @@ void adjust_mp3entry(struct mp3entry *entry, void *dest, void *orig)
1192 entry->comment += offset; 1194 entry->comment += offset;
1193 if (entry->albumartist) 1195 if (entry->albumartist)
1194 entry->albumartist += offset; 1196 entry->albumartist += offset;
1197 if (entry->grouping)
1198 entry->grouping += offset;
1195#if CONFIG_CODEC == SWCODEC 1199#if CONFIG_CODEC == SWCODEC
1196 if (entry->track_gain_string) 1200 if (entry->track_gain_string)
1197 entry->track_gain_string += offset; 1201 entry->track_gain_string += offset;