diff options
-rw-r--r-- | apps/gui/gwps-common.c | 3 | ||||
-rw-r--r-- | apps/gui/gwps.h | 1 | ||||
-rw-r--r-- | apps/gui/wps_debug.c | 5 | ||||
-rw-r--r-- | apps/gui/wps_parser.c | 2 | ||||
-rw-r--r-- | apps/lang/deutsch.lang | 14 | ||||
-rw-r--r-- | apps/lang/english.lang | 14 | ||||
-rw-r--r-- | apps/metadata/metadata_common.c | 12 | ||||
-rw-r--r-- | apps/metadata/mp4.c | 6 | ||||
-rw-r--r-- | apps/screens.c | 30 | ||||
-rw-r--r-- | apps/tagcache.c | 28 | ||||
-rw-r--r-- | apps/tagcache.h | 6 | ||||
-rw-r--r-- | apps/tagtree.c | 1 | ||||
-rw-r--r-- | docs/CREDITS | 1 | ||||
-rw-r--r-- | firmware/export/id3.h | 1 | ||||
-rw-r--r-- | firmware/id3.c | 6 |
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). */ |
110 | static const int sorted_tags[] = { tag_artist, tag_album, tag_genre, | 110 | static 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). */ |
114 | static const int unique_tags[] = { tag_artist, tag_album, tag_genre, | 114 | static 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). */ |
118 | static const int numeric_tags[] = { tag_year, tag_discnumber, tag_tracknumber, tag_length, | 118 | 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 | |||
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! */ |
125 | static const char *tags_str[] = { "artist", "album", "genre", "title", | 125 | static 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 */ |
190 | static const char *tagfile_entry_ec = "ss"; | 190 | static const char *tagfile_entry_ec = "ss"; |
191 | static const char *index_entry_ec = "lllllllllllllllllll"; /* (1 + TAG_COUNT) * l */ | 191 | static const char *index_entry_ec = "llllllllllllllllllll"; /* (1 + TAG_COUNT) * l */ |
192 | static const char *tagcache_header_ec = "lll"; | 192 | static const char *tagcache_header_ec = "lll"; |
193 | static const char *master_header_ec = "llllll"; | 193 | static 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 | ||
25 | enum tag_type { tag_artist = 0, tag_album, tag_genre, tag_title, | 25 | enum 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 | |||
311 | John Zhou | 311 | John Zhou |
312 | Charles Voelger | 312 | Charles Voelger |
313 | Gerritt Gonzales | 313 | Gerritt Gonzales |
314 | Dieter Pellkofer | ||
314 | The libmad team | 315 | The libmad team |
315 | The wavpack team | 316 | The wavpack team |
316 | The ffmpeg team | 317 | The 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; |