Index: apps/metadata.c =================================================================== --- apps/metadata.c (revision 13614) +++ apps/metadata.c (working copy) @@ -74,6 +74,9 @@ #define MP4_mp4a MP4_ID('m', 'p', '4', 'a') #define MP4_mp42 MP4_ID('m', 'p', '4', '2') #define MP4_qt MP4_ID('q', 't', ' ', ' ') +#define MP4_soal MP4_ID('s', 'o', 'a', 'l') +#define MP4_soar MP4_ID('s', 'o', 'a', 'r') +#define MP4_sonm MP4_ID('s', 'o', 'n', 'm') #define MP4_soun MP4_ID('s', 'o', 'u', 'n') #define MP4_stbl MP4_ID('s', 't', 'b', 'l') #define MP4_stsd MP4_ID('s', 't', 's', 'd') @@ -274,6 +277,20 @@ { p = &(id3->albumartist); } +#ifdef HAVE_TAGCACHE + else if (strcasecmp(name, "artistsort") == 0) + { + p = &(id3->sort_artist); + } + else if (strcasecmp(name, "albumsort") == 0) + { + p = &(id3->sort_album); + } + else if (strcasecmp(name, "titlesort") == 0) + { + p = &(id3->sort_title); + } +#endif else { len = parse_replaygain(name, value, id3, buf, buf_remaining); @@ -1479,7 +1496,22 @@ id3->genre_string = id3_get_num_genre(betoh16(genre) - 1); } break; +#ifdef HAVE_TAGCACHE + case MP4_soal: + read_mp4_tag_string(fd, size, &buffer, &buffer_left, + &id3->sort_album); + break; + case MP4_soar: + read_mp4_tag_string(fd, size, &buffer, &buffer_left, + &id3->sort_artist); + break; + + case MP4_sonm: + read_mp4_tag_string(fd, size, &buffer, &buffer_left, + &id3->sort_title); + break; +#endif case MP4_trkn: { unsigned short n[2]; Index: apps/tagcache.c =================================================================== --- apps/tagcache.c (revision 13614) +++ apps/tagcache.c (working copy) @@ -108,11 +108,13 @@ /* 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_title, tag_sortartist, + tag_sortalbum, tag_sorttitle }; /* 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_sortartist, tag_sortalbum, + tag_sorttitle }; /* Numeric tags (we can use these tags with conditional clauses). */ static const int numeric_tags[] = { tag_year, tag_tracknumber, tag_length, @@ -124,7 +126,8 @@ /* 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", - "bitrate", "length", "playcount", "rating", "playtime", "lastplayed", "commitid" }; + "bitrate", "length", "playcount", "rating", "playtime", "lastplayed", "commitid", + "sortartist", "sortalbum", "sorttitle" }; /* Status information of the tagcache. */ static struct tagcache_stat tc_stat; @@ -170,7 +173,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 = "lllllllllllllllllllll"; /* (1 + TAG_COUNT) * l */ static const char *tagcache_header_ec = "lll"; static const char *master_header_ec = "llllll"; @@ -1531,6 +1534,9 @@ 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->sort_title = get_tag_string(entry, tag_sorttitle); + id3->sort_artist = get_tag_string(entry, tag_sortartist); + id3->sort_album = get_tag_string(entry, tag_sortalbum); id3->playcount = get_tag_numeric(entry, tag_playcount); id3->rating = get_tag_numeric(entry, tag_rating); @@ -1693,6 +1699,9 @@ ADD_TAG(entry, tag_composer, &track.id3.composer); ADD_TAG(entry, tag_comment, &track.id3.comment); ADD_TAG(entry, tag_albumartist, &track.id3.albumartist); + ADD_TAG(entry, tag_sorttitle, &track.id3.sort_title); + ADD_TAG(entry, tag_sortartist, &track.id3.sort_artist); + ADD_TAG(entry, tag_sortalbum, &track.id3.sort_album); entry.data_length = offset; /* Write the header */ @@ -1706,7 +1715,9 @@ write_item(track.id3.genre_string); write_item(track.id3.composer); write_item(track.id3.comment); - write_item(track.id3.albumartist); + write_item(track.id3.sort_title); + write_item(track.id3.sort_artist); + write_item(track.id3.sort_album); total_entry_count++; } Index: apps/tagcache.h =================================================================== --- apps/tagcache.h (revision 13614) +++ apps/tagcache.h (working copy) @@ -25,13 +25,14 @@ enum tag_type { tag_artist = 0, tag_album, tag_genre, tag_title, tag_filename, tag_composer, tag_comment, tag_albumartist, tag_year, tag_tracknumber, tag_bitrate, tag_length, tag_playcount, tag_rating, - tag_playtime, tag_lastplayed, tag_commitid, + tag_playtime, tag_lastplayed, tag_commitid, tag_sortartist, + tag_sortalbum, tag_sorttitle, /* Virtual tags */ tag_virt_length_min, tag_virt_length_sec, tag_virt_playtime_min, tag_virt_playtime_sec, tag_virt_entryage, tag_virt_autoscore }; -#define TAG_COUNT 17 +#define TAG_COUNT 20 /* Maximum length of a single tag. */ #define TAG_MAXLEN (MAX_PATH*2) Index: firmware/export/id3.h =================================================================== --- firmware/export/id3.h (revision 13614) +++ firmware/export/id3.h (working copy) @@ -149,6 +149,11 @@ char* composer; char* comment; char* albumartist; +#ifdef HAVE_TAGCACHE + char* sort_title; + char* sort_album; + char* sort_artist; +#endif int tracknum; int version; int layer; Index: firmware/id3.c =================================================================== --- firmware/id3.c (revision 13614) +++ firmware/id3.c (working copy) @@ -449,10 +449,18 @@ { "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 }, { "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 }, +#ifdef HAVE_TAGCACHE + { "XSOA", 4, offsetof(struct mp3entry, sort_album), NULL, false }, + { "XSOP", 4, offsetof(struct mp3entry, sort_artist), NULL, false }, + { "XSOT", 4, offsetof(struct mp3entry, sort_title), NULL, false }, + { "TSOA", 4, offsetof(struct mp3entry, sort_album), NULL, false }, + { "TSOP", 4, offsetof(struct mp3entry, sort_artist), NULL, false }, + { "TSOT", 4, offsetof(struct mp3entry, sort_title), NULL, false }, +#endif #if CONFIG_CODEC == SWCODEC { "TXXX", 4, 0, &parseuser, false }, { "RVA2", 4, 0, &parserva2, true },