2 * Copyright (C) 2008-2012 Paul Davis <paul@linuxaudiosystems.com>
3 * Copyright (C) 2009-2012 Carl Hetherington <carl@carlh.net>
4 * Copyright (C) 2009 David Robillard <d@drobilla.net>
5 * Copyright (C) 2015-2019 Robin Gareus <robin@gareus.org>
6 * Copyright (C) 2015 Colin Fletcher <colin.m.fletcher@googlemail.com>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "ardour/session_metadata.h"
30 using namespace ARDOUR;
32 SessionMetadata *SessionMetadata::_metadata = NULL; //singleton instance
34 SessionMetadata::SessionMetadata ()
37 map.insert (Property ("description", ""));
39 /*** Track/Song Data ***/
40 map.insert (Property ("comment", ""));
41 map.insert (Property ("copyright", ""));
42 map.insert (Property ("isrc", ""));
43 map.insert (Property ("year", ""));
45 /*** Title and friends ***/
46 map.insert (Property ("grouping", ""));
47 map.insert (Property ("title", ""));
48 map.insert (Property ("subtitle", ""));
51 map.insert (Property ("artist", ""));
52 map.insert (Property ("album_artist", ""));
53 map.insert (Property ("lyricist", ""));
54 map.insert (Property ("composer", ""));
55 map.insert (Property ("conductor", ""));
56 map.insert (Property ("remixer", ""));
57 map.insert (Property ("arranger", ""));
58 map.insert (Property ("engineer", ""));
59 map.insert (Property ("producer", ""));
60 map.insert (Property ("dj_mixer", ""));
61 map.insert (Property ("mixer", ""));
62 //map.insert (Property ("performers", "")); // Multiple values [instrument]
64 /*** Education... ***/
65 map.insert (Property ("instructor", ""));
66 map.insert (Property ("course", ""));
69 map.insert (Property ("album", ""));
70 map.insert (Property ("compilation", ""));
71 map.insert (Property ("disc_subtitle", ""));
72 map.insert (Property ("disc_number", ""));
73 map.insert (Property ("total_discs", ""));
74 map.insert (Property ("track_number", ""));
75 map.insert (Property ("total_tracks", ""));
78 map.insert (Property ("genre", ""));
79 //map.insert (Property ("mood", ""));
80 //map.insert (Property ("bpm", ""));
83 //map.insert (Property ("lyrics", ""));
84 //map.insert (Property ("media", ""));
85 //map.insert (Property ("label", ""));
86 map.insert (Property ("barcode", ""));
87 //map.insert (Property ("encoded_by", ""));
88 //map.insert (Property ("catalog_number", ""));
90 /*** Sorting orders ***/
91 //map.insert (Property ("album_sort", ""));
92 //map.insert (Property ("album_artist_sort", ""));
93 //map.insert (Property ("artist_sort", ""));
94 //map.insert (Property ("title_sort", ""));
97 user_map.insert (Property ("user_name", ""));
98 user_map.insert (Property ("user_email", ""));
99 user_map.insert (Property ("user_web", ""));
100 user_map.insert (Property ("user_organization", ""));
101 user_map.insert (Property ("user_country", ""));
104 SessionMetadata::~SessionMetadata ()
110 SessionMetadata::get_xml (const string & name)
112 string value = get_value (name);
117 XMLNode val ("value", value);
118 XMLNode * node = new XMLNode (name);
119 node->add_child_copy (val);
125 SessionMetadata::get_value (const string & name) const
127 PropertyMap::const_iterator it = map.find (name);
128 if (it == map.end()) {
129 it = user_map.find (name);
130 if (it == user_map.end()) {
131 // Should not be reached, except if loading metadata from a newer version with a new type
132 std::cerr << "Programming error in SessionMetadata::get_value (" << name << ")" << std::endl;
141 SessionMetadata::get_uint_value (const string & name) const
143 return atoi (get_value (name).c_str());
147 SessionMetadata::set_value (const string & name, const string & value)
149 PropertyMap::iterator it = map.find (name);
150 if (it == map.end()) {
151 it = user_map.find (name);
152 if (it == user_map.end()) {
153 // Should not be reached, except if loading metadata from a newer version with a new type
154 std::cerr << "Programming error in SessionMetadata::set_value (" << name << ")" << std::endl;
163 SessionMetadata::set_value (const string & name, uint32_t value)
165 std::ostringstream oss;
167 if (oss.str().compare("0")) {
168 set_value (name, oss.str());
170 set_value (name, "");
174 /*** Serialization ***/
176 SessionMetadata::get_state ()
178 XMLNode * node = new XMLNode ("Metadata");
181 for (PropertyMap::const_iterator it = map.begin(); it != map.end(); ++it) {
182 if ((prop = get_xml (it->first))) {
183 node->add_child_nocopy (*prop);
191 SessionMetadata::set_state (const XMLNode & state, int /*version_num*/)
193 const XMLNodeList & children = state.children();
198 for (XMLNodeConstIterator it = children.begin(); it != children.end(); it++) {
200 if (node->children().empty()) {
205 node = *node->children().begin();
206 value = node->content();
208 set_value (name, value);
216 SessionMetadata::get_user_state ()
218 XMLNode * node = new XMLNode ("Metadata");
221 for (PropertyMap::const_iterator it = user_map.begin(); it != user_map.end(); ++it) {
222 if ((prop = get_xml (it->first))) {
223 node->add_child_nocopy (*prop);
232 SessionMetadata::description () const
234 return get_value("description");
238 SessionMetadata::comment () const
240 return get_value("comment");
244 SessionMetadata::copyright () const
246 return get_value("copyright");
250 SessionMetadata::isrc () const
252 return get_value("isrc");
256 SessionMetadata::year () const
258 return get_uint_value("year");
262 SessionMetadata::grouping () const
264 return get_value("grouping");
268 SessionMetadata::barcode () const
270 return get_value("barcode");
274 SessionMetadata::title () const
276 return get_value("title");
280 SessionMetadata::subtitle () const
282 return get_value("subtitle");
286 SessionMetadata::artist () const
288 return get_value("artist");
292 SessionMetadata::album_artist () const
294 return get_value("album_artist");
298 SessionMetadata::lyricist () const
300 return get_value("lyricist");
304 SessionMetadata::composer () const
306 return get_value("composer");
310 SessionMetadata::conductor () const
312 return get_value("conductor");
316 SessionMetadata::remixer () const
318 return get_value("remixer");
322 SessionMetadata::arranger () const
324 return get_value("arranger");
328 SessionMetadata::engineer () const
330 return get_value("engineer");
334 SessionMetadata::producer () const
336 return get_value("producer");
340 SessionMetadata::dj_mixer () const
342 return get_value("dj_mixer");
346 SessionMetadata::mixer () const
348 return get_value("mixer");
352 SessionMetadata::album () const
354 return get_value("album");
358 SessionMetadata::compilation () const
360 return get_value("compilation");
364 SessionMetadata::disc_subtitle () const
366 return get_value("disc_subtitle");
370 SessionMetadata::disc_number () const
372 return get_uint_value("disc_number");
376 SessionMetadata::total_discs () const
378 return get_uint_value("total_discs");
382 SessionMetadata::track_number () const
384 return get_uint_value("track_number");
388 SessionMetadata::total_tracks () const
390 return get_uint_value("total_tracks");
394 SessionMetadata::genre () const
396 return get_value("genre");
400 SessionMetadata::instructor () const
402 return get_value("instructor");
406 SessionMetadata::course () const
408 return get_value("course");
413 SessionMetadata::user_name () const
415 return get_value("user_name");
419 SessionMetadata::user_email () const
421 return get_value("user_email");
425 SessionMetadata::user_web () const
427 return get_value("user_web");
431 SessionMetadata::organization () const
433 return get_value("user_organization");
437 SessionMetadata::country () const
439 return get_value("user_country");
446 SessionMetadata::set_description (const string & v)
448 set_value ("description", v);
452 SessionMetadata::set_comment (const string & v)
454 set_value ("comment", v);
458 SessionMetadata::set_copyright (const string & v)
460 set_value ("copyright", v);
464 SessionMetadata::set_isrc (const string & v)
466 set_value ("isrc", v);
470 SessionMetadata::set_year (uint32_t v)
472 set_value ("year", v);
476 SessionMetadata::set_grouping (const string & v)
478 set_value ("grouping", v);
482 SessionMetadata::set_barcode (const string & v)
484 set_value ("barcode", v);
488 SessionMetadata::set_title (const string & v)
490 set_value ("title", v);
494 SessionMetadata::set_subtitle (const string & v)
496 set_value ("subtitle", v);
500 SessionMetadata::set_artist (const string & v)
502 set_value ("artist", v);
506 SessionMetadata::set_album_artist (const string & v)
508 set_value ("album_artist", v);
512 SessionMetadata::set_lyricist (const string & v)
514 set_value ("lyricist", v);
518 SessionMetadata::set_composer (const string & v)
520 set_value ("composer", v);
524 SessionMetadata::set_conductor (const string & v)
526 set_value ("conductor", v);
530 SessionMetadata::set_remixer (const string & v)
532 set_value ("remixer", v);
536 SessionMetadata::set_arranger (const string & v)
538 set_value ("arranger", v);
542 SessionMetadata::set_engineer (const string & v)
544 set_value ("engineer", v);
548 SessionMetadata::set_producer (const string & v)
550 set_value ("producer", v);
554 SessionMetadata::set_dj_mixer (const string & v)
556 set_value ("dj_mixer", v);
560 SessionMetadata::set_mixer (const string & v)
562 set_value ("mixer", v);
566 SessionMetadata::set_album (const string & v)
568 set_value ("album", v);
572 SessionMetadata::set_compilation (const string & v)
574 set_value ("compilation", v);
578 SessionMetadata::set_disc_subtitle (const string & v)
580 set_value ("disc_subtitle", v);
584 SessionMetadata::set_disc_number (uint32_t v)
586 set_value ("disc_number", v);
590 SessionMetadata::set_total_discs (uint32_t v)
592 set_value ("total_discs", v);
596 SessionMetadata::set_track_number (uint32_t v)
598 set_value ("track_number", v);
602 SessionMetadata::set_total_tracks (uint32_t v)
604 set_value ("total_tracks", v);
608 SessionMetadata::set_genre (const string & v)
610 set_value ("genre", v);
614 SessionMetadata::set_instructor (const string & v)
616 set_value ("instructor", v);
620 SessionMetadata::set_course (const string & v)
622 set_value ("course", v);
626 SessionMetadata::set_user_name (const string & v)
628 set_value ("user_name", v);
632 SessionMetadata::set_user_email (const string & v)
634 set_value ("user_email", v);
638 SessionMetadata::set_user_web (const string & v)
640 set_value ("user_web", v);
644 SessionMetadata::set_organization (const string & v)
646 set_value ("user_organization", v);
649 SessionMetadata::set_country (const string & v)
651 set_value ("user_country", v);
655 SessionMetadata::av_export_tag (MetaDataMap& meta) const
657 /* this is used for ffmpeg/liblame -metadata key=value
658 * (video and mp3 export).
659 * for flac/ogg's vorbis-comment see:
660 * AudiofileTagger::tag_generic()
661 * AudiofileTagger::tag_vorbis_comment()
664 std::ostringstream osstream; osstream << year();
665 meta["year"] = osstream.str();
667 if (track_number() > 0) {
668 std::ostringstream osstream; osstream << track_number();
669 meta["track"] = osstream.str();
671 if (disc_number() > 0) {
672 std::ostringstream osstream; osstream << disc_number();
673 meta["disc"] = osstream.str();
675 if (!title().empty()) { meta["title"] = title(); }
676 if (!artist().empty()) { meta["author"] = artist(); }
677 if (!album_artist().empty()) { meta["album_artist"] = album_artist(); }
678 if (!album().empty()) { meta["album"] = album(); }
679 if (!genre().empty()) { meta["genre"] = genre(); }
680 if (!composer().empty()) { meta["composer"] = composer(); }
681 if (!comment().empty()) { meta["comment"] = comment(); }
682 if (!copyright().empty()) { meta["copyright"] = copyright(); }
683 if (!subtitle().empty()) { meta["description"] = subtitle(); }