summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/gui/gwps-common.c9
-rw-r--r--apps/gui/gwps.h1
-rw-r--r--apps/gui/wps_debug.c4
-rw-r--r--apps/gui/wps_parser.c2
-rw-r--r--apps/lang/english.lang14
-rw-r--r--apps/metadata/metadata_common.c5
-rw-r--r--apps/metadata/mp4.c10
-rw-r--r--apps/screens.c34
-rw-r--r--apps/tagcache.c8
-rw-r--r--apps/tagcache.h6
-rw-r--r--apps/tagnavi.config1
-rw-r--r--apps/tagtree.c1
-rw-r--r--docs/CREDITS1
-rw-r--r--firmware/export/id3.h2
-rw-r--r--firmware/id3.c13
15 files changed, 92 insertions, 19 deletions
diff --git a/apps/gui/gwps-common.c b/apps/gui/gwps-common.c
index 2c5238b972..9dddff3ea2 100644
--- a/apps/gui/gwps-common.c
+++ b/apps/gui/gwps-common.c
@@ -876,6 +876,15 @@ static char *get_token_value(struct gui_wps *gwps,
case WPS_TOKEN_METADATA_GENRE:
return id3->genre_string;
+ case WPS_TOKEN_METADATA_DISC_NUMBER:
+ if (id3->disc_string)
+ return id3->disc_string;
+ if (id3->discnum) {
+ snprintf(buf, buf_size, "%d", id3->discnum);
+ return buf;
+ }
+ return NULL;
+
case WPS_TOKEN_METADATA_TRACK_NUMBER:
if (id3->track_string)
return id3->track_string;
diff --git a/apps/gui/gwps.h b/apps/gui/gwps.h
index 371b2b0399..b02b87f2c9 100644
--- a/apps/gui/gwps.h
+++ b/apps/gui/gwps.h
@@ -193,6 +193,7 @@ enum wps_token_type {
WPS_TOKEN_METADATA_ALBUM_ARTIST,
WPS_TOKEN_METADATA_ALBUM,
WPS_TOKEN_METADATA_GENRE,
+ WPS_TOKEN_METADATA_DISC_NUMBER,
WPS_TOKEN_METADATA_TRACK_NUMBER,
WPS_TOKEN_METADATA_TRACK_TITLE,
WPS_TOKEN_METADATA_VERSION,
diff --git a/apps/gui/wps_debug.c b/apps/gui/wps_debug.c
index 0f40a57801..50ffcce119 100644
--- a/apps/gui/wps_debug.c
+++ b/apps/gui/wps_debug.c
@@ -294,6 +294,10 @@ static void dump_wps_tokens(struct wps_data *data)
next_str(next));
break;
+ case WPS_TOKEN_METADATA_DISC_NUMBER:
+ snprintf(buf, sizeof(buf), "%strack disc", next_str(next));
+ break;
+
case WPS_TOKEN_METADATA_TRACK_NUMBER:
snprintf(buf, sizeof(buf), "%strack number",
next_str(next));
diff --git a/apps/gui/wps_parser.c b/apps/gui/wps_parser.c
index 86b74129f2..d66e47dfe7 100644
--- a/apps/gui/wps_parser.c
+++ b/apps/gui/wps_parser.c
@@ -201,6 +201,7 @@ static const struct wps_tag all_tags[] = {
{ WPS_TOKEN_METADATA_ALBUM, "id", WPS_REFRESH_STATIC, NULL },
{ WPS_TOKEN_METADATA_ALBUM_ARTIST, "iA", 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_TRACK_NUMBER, "in", WPS_REFRESH_STATIC, NULL },
{ WPS_TOKEN_METADATA_TRACK_TITLE, "it", WPS_REFRESH_STATIC, NULL },
{ WPS_TOKEN_METADATA_VERSION, "iv", WPS_REFRESH_STATIC, NULL },
@@ -213,6 +214,7 @@ static const struct wps_tag all_tags[] = {
{ WPS_TOKEN_METADATA_ALBUM, "Id", WPS_REFRESH_DYNAMIC, NULL },
{ WPS_TOKEN_METADATA_ALBUM_ARTIST, "IA", 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_TRACK_NUMBER, "In", WPS_REFRESH_DYNAMIC, NULL },
{ WPS_TOKEN_METADATA_TRACK_TITLE, "It", WPS_REFRESH_DYNAMIC, NULL },
{ WPS_TOKEN_METADATA_VERSION, "Iv", WPS_REFRESH_DYNAMIC, NULL },
diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 2dcb7bc4ef..dcace6db8c 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -11054,3 +11054,17 @@
*: "Can't write to recording directory"
</voice>
</phrase>
+<phrase>
+ id: LANG_ID3_DISCNUM
+ desc: in tag viewer
+ user:
+ <source>
+ *: "[Discnum]"
+ </source>
+ <dest>
+ *: "[Discnum]"
+ </dest>
+ <voice>
+ *: ""
+ </voice>
+</phrase> \ No newline at end of file
diff --git a/apps/metadata/metadata_common.c b/apps/metadata/metadata_common.c
index d81d9f71d3..d1a1087188 100644
--- a/apps/metadata/metadata_common.c
+++ b/apps/metadata/metadata_common.c
@@ -224,6 +224,11 @@ long parse_tag(const char* name, char* value, struct mp3entry* id3,
id3->tracknum = atoi(value);
p = &(id3->track_string);
}
+ else if (strcasecmp(name, "discnumber") == 0 || strcasecmp(name, "disc") == 0)
+ {
+ id3->discnum = atoi(value);
+ p = &(id3->disc_string);
+ }
else if (((strcasecmp(name, "year") == 0) && (type == TAGTYPE_APE))
|| ((strcasecmp(name, "date") == 0) && (type == TAGTYPE_VORBIS)))
{
diff --git a/apps/metadata/mp4.c b/apps/metadata/mp4.c
index 591d020373..3293007870 100644
--- a/apps/metadata/mp4.c
+++ b/apps/metadata/mp4.c
@@ -43,6 +43,7 @@
#define MP4_cwrt MP4_ID(0xa9, 'w', 'r', 't')
#define MP4_ccmt MP4_ID(0xa9, 'c', 'm', 't')
#define MP4_cday MP4_ID(0xa9, 'd', 'a', 'y')
+#define MP4_disk MP4_ID('d', 'i', 's', 'k')
#define MP4_esds MP4_ID('e', 's', 'd', 's')
#define MP4_ftyp MP4_ID('f', 't', 'y', 'p')
#define MP4_gnre MP4_ID('g', 'n', 'r', 'e')
@@ -422,6 +423,15 @@ static bool read_mp4_tags(int fd, struct mp3entry* id3,
&id3->genre_string);
break;
+ case MP4_disk:
+ {
+ unsigned short n[2];
+
+ read_mp4_tag(fd, size, (char*) &n, sizeof(n));
+ id3->disknum = betoh16(n[1]);
+ }
+ break;
+
case MP4_trkn:
{
unsigned short n[2];
diff --git a/apps/screens.c b/apps/screens.c
index d88eb1167b..b2436f00f1 100644
--- a/apps/screens.c
+++ b/apps/screens.c
@@ -1151,6 +1151,7 @@ static const int id3_headers[]=
LANG_ID3_ARTIST,
LANG_ID3_ALBUM,
LANG_ID3_ALBUMARTIST,
+ LANG_ID3_DISCNUM,
LANG_ID3_TRACKNUM,
LANG_ID3_COMMENT,
LANG_ID3_GENRE,
@@ -1192,7 +1193,16 @@ static char * id3_get_info(int selected_item, void* data, char *buffer)
case 3:/*LANG_ID3_ALBUMARTIST*/
info=id3->albumartist;
break;
- case 4:/*LANG_ID3_TRACKNUM*/
+ case 4:/*LANG_ID3_DISCNUM*/
+ if (id3->disc_string)
+ info = id3->disc_string;
+ else if (id3->discnum)
+ {
+ snprintf(buffer, MAX_PATH, "%d", id3->discnum);
+ info = buffer;
+ }
+ break;
+ case 5:/*LANG_ID3_TRACKNUM*/
if (id3->track_string)
info = id3->track_string;
else if (id3->tracknum)
@@ -1201,13 +1211,13 @@ static char * id3_get_info(int selected_item, void* data, char *buffer)
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)
@@ -1216,34 +1226,34 @@ static char * id3_get_info(int selected_item, void* data, char *buffer)
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_FREQUENCY*/
+ case 12:/*LANG_ID3_FREQUENCY*/
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;
diff --git a/apps/tagcache.c b/apps/tagcache.c
index 6d738bc5fb..da51e0c4e9 100644
--- a/apps/tagcache.c
+++ b/apps/tagcache.c
@@ -115,7 +115,7 @@ static const int unique_tags[] = { tag_artist, tag_album, tag_genre,
tag_composer, tag_comment, tag_albumartist };
/* Numeric tags (we can use these tags with conditional clauses). */
-static const int numeric_tags[] = { tag_year, tag_tracknumber, tag_length,
+static const int numeric_tags[] = { tag_year, tag_discnumber, tag_tracknumber, tag_length,
tag_bitrate, tag_playcount, tag_rating, tag_playtime, tag_lastplayed, tag_commitid,
tag_virt_length_min, tag_virt_length_sec,
tag_virt_playtime_min, tag_virt_playtime_sec,
@@ -123,7 +123,7 @@ static const int numeric_tags[] = { tag_year, tag_tracknumber, tag_length,
/* 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", "year", "discnumber", "tracknumber",
"bitrate", "length", "playcount", "rating", "playtime", "lastplayed", "commitid" };
/* Status information of the tagcache. */
@@ -188,7 +188,7 @@ struct master_header {
/* 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";
@@ -1556,6 +1556,7 @@ bool tagcache_fill_tags(struct mp3entry *id3, const char *filename)
id3->score = get_tag_numeric(entry, tag_virt_autoscore) / 10;
id3->year = get_tag_numeric(entry, tag_year);
+ id3->discnum = get_tag_numeric(entry, tag_discnumber);
id3->tracknum = get_tag_numeric(entry, tag_tracknumber);
id3->bitrate = get_tag_numeric(entry, tag_bitrate);
if (id3->bitrate == 0)
@@ -1699,6 +1700,7 @@ static void add_tagcache(char *path)
/* Numeric tags */
entry.tag_offset[tag_year] = track.id3.year;
+ entry.tag_offset[tag_discnumber] = track.id3.discnum;
entry.tag_offset[tag_tracknumber] = track.id3.tracknum;
entry.tag_offset[tag_length] = track.id3.length;
entry.tag_offset[tag_bitrate] = track.id3.bitrate;
diff --git a/apps/tagcache.h b/apps/tagcache.h
index 3d80c6975f..ada624783a 100644
--- a/apps/tagcache.h
+++ b/apps/tagcache.h
@@ -24,14 +24,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_discnumber, tag_tracknumber, tag_bitrate, tag_length, tag_playcount, tag_rating,
tag_playtime, tag_lastplayed, tag_commitid,
/* 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 18
/* Maximum length of a single tag. */
#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
/* 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
diff --git a/apps/tagnavi.config b/apps/tagnavi.config
index 2c5675f5b7..2a98a7f93b 100644
--- a/apps/tagnavi.config
+++ b/apps/tagnavi.config
@@ -6,6 +6,7 @@
# get overwritten automatically.
# Basic format declarations
+%format "fmt_title" "%d.%02d. %s" discnum tracknum title ? discnum > "0"
%format "fmt_title" "%02d. %s - %02d:%02d" tracknum title Lm Ls ? tracknum > "0"
%format "fmt_title" "%s - %02d:%02d" title Lm Ls
%format "fmt_mostplayed" "%2d|%3d %s (%s)" playcount autoscore title artist %sort = "inverse" %limit = "100"
diff --git a/apps/tagtree.c b/apps/tagtree.c
index 271f30ffa8..06150c1f26 100644
--- a/apps/tagtree.c
+++ b/apps/tagtree.c
@@ -209,6 +209,7 @@ static int get_tag(int *tag)
MATCH(tag, buf, "title", tag_title);
MATCH(tag, buf, "filename", tag_filename);
MATCH(tag, buf, "tracknum", tag_tracknumber);
+ MATCH(tag, buf, "discnum", tag_discnumber);
MATCH(tag, buf, "year", tag_year);
MATCH(tag, buf, "playcount", tag_playcount);
MATCH(tag, buf, "rating", tag_rating);
diff --git a/docs/CREDITS b/docs/CREDITS
index ff9658e322..e84521ba8f 100644
--- a/docs/CREDITS
+++ b/docs/CREDITS
@@ -309,6 +309,7 @@ Johnathon Mihalop
Rene Allkivi
Tobias Schladt
John Zhou
+Charles Voelger
The libmad team
The wavpack team
The ffmpeg team
diff --git a/firmware/export/id3.h b/firmware/export/id3.h
index 3b69d50075..8c91456040 100644
--- a/firmware/export/id3.h
+++ b/firmware/export/id3.h
@@ -147,11 +147,13 @@ struct mp3entry {
char* artist;
char* album;
char* genre_string;
+ char* disc_string;
char* track_string;
char* year_string;
char* composer;
char* comment;
char* albumartist;
+ int discnum;
int tracknum;
int version;
int layer;
diff --git a/firmware/id3.c b/firmware/id3.c
index 8e1d96462b..a66318b2fc 100644
--- a/firmware/id3.c
+++ b/firmware/id3.c
@@ -352,6 +352,13 @@ static int parsetracknum( struct mp3entry* entry, char* tag, int bufferpos )
}
/* parse numeric value from string */
+static int parsediscnum( struct mp3entry* entry, char* tag, int bufferpos )
+{
+ entry->discnum = atoi( tag );
+ return bufferpos;
+}
+
+/* parse numeric value from string */
static int parseyearnum( struct mp3entry* entry, char* tag, int bufferpos )
{
entry->year = atoi( tag );
@@ -446,6 +453,7 @@ static const struct tag_resolver taglist[] = {
{ "TALB", 4, offsetof(struct mp3entry, album), NULL, false },
{ "TAL", 3, offsetof(struct mp3entry, album), NULL, false },
{ "TRK", 3, offsetof(struct mp3entry, track_string), &parsetracknum, false },
+ { "TPOS", 4, offsetof(struct mp3entry, disc_string), &parsediscnum, false },
{ "TRCK", 4, offsetof(struct mp3entry, track_string), &parsetracknum, false },
{ "TDRC", 4, offsetof(struct mp3entry, year_string), &parseyearnum, false },
{ "TYER", 4, offsetof(struct mp3entry, year_string), &parseyearnum, false },
@@ -693,7 +701,7 @@ static void setid3v2title(int fd, struct mp3entry *entry)
return;
}
entry->id3version = version;
- entry->tracknum = entry->year = 0;
+ entry->tracknum = entry->year = entry->discnum = 0;
entry->title = entry->artist = entry->album = NULL; /* FIXME incomplete */
global_flags = header[5];
@@ -1112,6 +1120,7 @@ bool get_mp3_metadata(int fd, struct mp3entry *entry, const char *filename, bool
entry->filesize = filesize(fd);
entry->id3v2len = getid3v2len(fd);
entry->tracknum = 0;
+ entry->discnum = 0;
if(v1first)
v1found = setid3v1title(fd, entry);
@@ -1173,6 +1182,8 @@ void adjust_mp3entry(struct mp3entry *entry, void *dest, void *orig)
entry->genre_string += offset;
if (entry->track_string)
entry->track_string += offset;
+ if (entry->disc_string)
+ entry->disc_string += offset;
if (entry->year_string)
entry->year_string += offset;
if (entry->composer)