Add support for parsing the disc number tag from metadata and use of it in the database. Patch originally from FS#4961 with some minor tweaks by me.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14154 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
1fbf847eed
commit
f4a61f0c4a
15 changed files with 92 additions and 19 deletions
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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>
|
|
@ -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)))
|
||||
{
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -309,6 +309,7 @@ Johnathon Mihalop
|
|||
Rene Allkivi
|
||||
Tobias Schladt
|
||||
John Zhou
|
||||
Charles Voelger
|
||||
The libmad team
|
||||
The wavpack team
|
||||
The ffmpeg team
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -351,6 +351,13 @@ static int parsetracknum( struct mp3entry* entry, char* tag, int bufferpos )
|
|||
return 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 )
|
||||
{
|
||||
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue