This patch adds some additional format options. However, right now they
are not too useful for two reasons:
* Lack of conditionals in format string
(e.g. we maybe only want to show the composer if one is present)
* Lack of proper handling of multiple values for a tag
(e.g. we want to join multiple composers, like "John Lennon / Paul
McCartney")
I plan to address both issues in the future, also the ability to use
them for filtering.
The added format options are:
ID3v2 additional freeform
-------------------------------------------
%{arranger}
%{composer} TCOM SONGWRITER
%{conductor} TPE3
%{lyricist} TEXT SONGWRITER
%{performer}
%{remixer} TPE4
%{label} TPUB
%{publisher} TPUB
%{work}
%{opus}
%{partnumber}
%{part}
%{subtitle} TIT3 VERSION
Notice that "songwriter" maps to both composer and lyricist, and
"version" is a synonym for "subtitle". Left to do is the ID3v2 mapping
for arranger and performer, which requires multi-value decoding of TMCL
and TIPL. Also "producer" could be added.
Further reading:
http://musicbrainz.org/doc/Picard_Tag_Mapping
http://age.hobba.nl/audio/mirroredpages/ogg-tagging.html
Suggested-by: Leon Merten Lohse <***@green-side.de>
---
Doc/cmus.txt | 13 +++++++++++++
comment.c | 9 +++++++++
id3.c | 15 +++++++++++++++
id3.h | 7 +++++++
ui_curses.c | 39 +++++++++++++++++++++++++++++++++++++++
5 files changed, 83 insertions(+), 0 deletions(-)
diff --git a/Doc/cmus.txt b/Doc/cmus.txt
index cb5d975..b34099f 100644
--- a/Doc/cmus.txt
+++ b/Doc/cmus.txt
@@ -984,6 +984,19 @@ Special Keys:
%{rg_track_peak} @br
%{rg_album_gain} @br
%{rg_album_peak} @br
+ %{arranger} @br
+ %{composer} @br
+ %{conductor} @br
+ %{lyricist} @br
+ %{performer} @br
+ %{remixer} @br
+ %{label} @br
+ %{publisher} @br
+ %{work} @br
+ %{opus} @br
+ %{partnumber} @br
+ %{part} @br
+ %{subtitle} @br
%=
start align right (use at most once)
%%
diff --git a/comment.c b/comment.c
index b2795a5..887df6c 100644
--- a/comment.c
+++ b/comment.c
@@ -167,6 +167,9 @@ static const char *interesting[] = {
"replaygain_album_peak",
"musicbrainz_trackid",
"comment",
+ "arranger", "composer", "conductor", "lyricist", "performer",
+ "remixer", "label", "publisher", "work", "opus", "partnumber", "part",
+ "subtitle",
NULL
};
@@ -183,6 +186,7 @@ static struct {
{ "WM/AlbumArtistSortOrder", "albumartistsort" },
{ "WM/OriginalReleaseYear", "originaldate" },
{ "MusicBrainz Track Id", "musicbrainz_trackid" },
+ { "version", "subtitle" },
{ NULL, NULL }
};
@@ -205,6 +209,11 @@ int comments_add(struct growing_keyvals *c, const char *key, char *val)
{
int i;
+ if (!strcasecmp(key, "songwriter")) {
+ int r = comments_add_const(c, "lyricist", val);
+ return comments_add(c, "composer", val) && r;
+ }
+
key = fix_key(key);
if (!key) {
free(val);
diff --git a/id3.c b/id3.c
index eb15a68..77d0457 100644
--- a/id3.c
+++ b/id3.c
@@ -253,6 +253,13 @@ const char * const id3_key_names[NUM_ID3_KEYS] = {
"replaygain_track_peak",
"replaygain_album_gain",
"replaygain_album_peak",
+ "composer",
+ "conductor",
+ "lyricist",
+ "remixer",
+ "label",
+ "publisher",
+ "subtitle",
"comment",
"musicbrainz_trackid",
};
@@ -553,6 +560,12 @@ static struct {
{ "XSOP", ID3_ARTISTSORT }, // obsolete
{ "TCMP", ID3_COMPILATION },
{ "TORY", ID3_ORIGINALDATE },
+ { "TCOM", ID3_COMPOSER },
+ { "TPE3", ID3_CONDUCTOR },
+ { "TEXT", ID3_LYRICIST },
+ { "TPE4", ID3_REMIXER },
+ { "TPUB", ID3_PUBLISHER }, // TPUB can be both publisher or label
+ { "TIT3", ID3_SUBTITLE },
/* obsolete frames (2.2.0) */
{ "TP1", ID3_ARTIST },
@@ -710,6 +723,8 @@ static void decode_normal(struct id3tag *id3, const char *buf, int len, int enco
*/
if (id3->v2[key])
return;
+ } else if (key == ID3_PUBLISHER) {
+ add_v2(id3, ID3_LABEL, strdup(out));
}
add_v2(id3, key, out);
diff --git a/id3.h b/id3.h
index 3516204..f1b5b7c 100644
--- a/id3.h
+++ b/id3.h
@@ -40,6 +40,13 @@ enum id3_key {
ID3_RG_TRACK_PEAK,
ID3_RG_ALBUM_GAIN,
ID3_RG_ALBUM_PEAK,
+ ID3_COMPOSER,
+ ID3_CONDUCTOR,
+ ID3_LYRICIST,
+ ID3_REMIXER,
+ ID3_LABEL,
+ ID3_PUBLISHER,
+ ID3_SUBTITLE,
ID3_COMMENT,
ID3_MUSICBRAINZ_TRACKID,
diff --git a/ui_curses.c b/ui_curses.c
index 69151b9..c1b75aa 100644
--- a/ui_curses.c
+++ b/ui_curses.c
@@ -233,6 +233,19 @@ enum {
TF_RG_TRACK_PEAK,
TF_RG_ALBUM_GAIN,
TF_RG_ALBUM_PEAK,
+ TF_ARRANGER,
+ TF_COMPOSER,
+ TF_CONDUCTOR,
+ TF_LYRICIST,
+ TF_PERFORMER,
+ TF_REMIXER,
+ TF_LABEL,
+ TF_PUBLISHER,
+ TF_WORK,
+ TF_OPUS,
+ TF_PARTNUMBER,
+ TF_PART,
+ TF_SUBTITLE,
NR_TFS
};
@@ -257,6 +270,19 @@ static struct format_option track_fopts[NR_TFS + 1] = {
DEF_FO_DOUBLE('\0', "rg_track_peak", 0),
DEF_FO_DOUBLE('\0', "rg_album_gain", 0),
DEF_FO_DOUBLE('\0', "rg_album_peak", 0),
+ DEF_FO_STR('\0', "arranger", 0),
+ DEF_FO_STR('\0', "composer", 0),
+ DEF_FO_STR('\0', "conductor", 0),
+ DEF_FO_STR('\0', "lyricist", 0),
+ DEF_FO_STR('\0', "performer", 0),
+ DEF_FO_STR('\0', "remixer", 0),
+ DEF_FO_STR('\0', "label", 0),
+ DEF_FO_STR('\0', "publisher", 0),
+ DEF_FO_STR('\0', "work", 0),
+ DEF_FO_STR('\0', "opus", 0),
+ DEF_FO_STR('\0', "partnumber", 0),
+ DEF_FO_STR('\0', "part", 0),
+ DEF_FO_STR('\0', "subtitle", 0),
DEF_FO_END
};
@@ -570,6 +596,19 @@ static void fill_track_fopts_track_info(struct track_info *info)
fopt_set_str(&track_fopts[TF_CODEC], info->codec);
fopt_set_str(&track_fopts[TF_CODEC_PROFILE], info->codec_profile);
fopt_set_str(&track_fopts[TF_PATHFILE], filename);
+ fopt_set_str(&track_fopts[TF_ARRANGER], keyvals_get_val(info->comments, "arranger"));
+ fopt_set_str(&track_fopts[TF_COMPOSER], keyvals_get_val(info->comments, "composer"));
+ fopt_set_str(&track_fopts[TF_CONDUCTOR], keyvals_get_val(info->comments, "conductor"));
+ fopt_set_str(&track_fopts[TF_LYRICIST], keyvals_get_val(info->comments, "lyricist"));
+ fopt_set_str(&track_fopts[TF_PERFORMER], keyvals_get_val(info->comments, "performer"));
+ fopt_set_str(&track_fopts[TF_REMIXER], keyvals_get_val(info->comments, "remixer"));
+ fopt_set_str(&track_fopts[TF_LABEL], keyvals_get_val(info->comments, "label"));
+ fopt_set_str(&track_fopts[TF_PUBLISHER], keyvals_get_val(info->comments, "publisher"));
+ fopt_set_str(&track_fopts[TF_WORK], keyvals_get_val(info->comments, "work"));
+ fopt_set_str(&track_fopts[TF_OPUS], keyvals_get_val(info->comments, "opus"));
+ fopt_set_str(&track_fopts[TF_PARTNUMBER], keyvals_get_val(info->comments, "partnumber"));
+ fopt_set_str(&track_fopts[TF_PART], keyvals_get_val(info->comments, "part"));
+ fopt_set_str(&track_fopts[TF_SUBTITLE], keyvals_get_val(info->comments, "subtitle"));
if (is_http_url(info->filename)) {
fopt_set_str(&track_fopts[TF_FILE], filename);
} else {
--
1.7.7.1