aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2012-08-22 19:17:54 +0200
committerJason A. Donenfeld <Jason@zx2c4.com>2012-08-22 19:17:54 +0200
commitbaf66899f53f176378fa7dfe7ff78f676e627307 (patch)
tree95b7f0f1abe847e7e59bd2e4f3c04e990b06bc98
parentAdd library display tool. (diff)
downloadmusic-file-organizer-baf66899f53f176378fa7dfe7ff78f676e627307.tar.xz
music-file-organizer-baf66899f53f176378fa7dfe7ff78f676e627307.zip
Extract disc total and utilize that too.
-rw-r--r--AudioFile.cpp36
-rw-r--r--AudioFile.h2
-rw-r--r--organizemusic.cpp8
-rw-r--r--readmusictags.cpp2
4 files changed, 41 insertions, 7 deletions
diff --git a/AudioFile.cpp b/AudioFile.cpp
index bbe1526..db782ec 100644
--- a/AudioFile.cpp
+++ b/AudioFile.cpp
@@ -21,10 +21,25 @@ template <typename T, typename M>
inline T extractTag(M &map, const char *key)
{
T ret = 0;
- std::stringstream stream(extractTag<std::string>(map, key));
+ std::istringstream stream(extractTag<std::string>(map, key));
stream >> ret;
return ret;
}
+/* Turn a string into a pair of integer types separated by a slash
+ * for any map class. */
+template <typename T1, typename T2, typename M>
+inline std::pair<T1, T2> extractTag(M &map, const char *key)
+{
+ std::pair<T1, T2> values;
+ values.first = 0;
+ values.second = 0;
+ char slash = '\0';
+ std::istringstream stream(extractTag<std::string>(map, key));
+ stream >> values.first >> slash >> values.second;
+ if (slash != '/')
+ values.second = 0;
+ return values;
+}
/* Turn a string into a bool, based on "1" and "true", for any map class. */
template <typename M>
inline bool extractTag(M &map, const char *key)
@@ -49,6 +64,15 @@ inline std::string extractTag(const TagLib::Ogg::FieldListMap &map, const char *
return std::string();
return map[key].front().to8Bit(true);
}
+/* Extract an integer pair out of an MP4 map. */
+template <typename T1, typename T2>
+inline std::pair<T1, T2> extractTag(const TagLib::MP4::ItemListMap &map, const char *key)
+{
+ if (!map[key].isValid())
+ return std::pair<T1, T2>(0, 0);
+ TagLib::MP4::Item::IntPair pair = map[key].toIntPair();
+ return std::pair<T1, T2>(pair.first, pair.second);
+}
/* Extract an integer out of an MP4 map. */
template <>
inline unsigned int extractTag(const TagLib::MP4::ItemListMap &map, const char *key)
@@ -79,6 +103,7 @@ AudioFile::AudioFile(const std::string &filename) :
m_filename(filename),
m_track(0),
m_disc(0),
+ m_discTotal(0),
m_bpm(0),
m_year(0),
m_length(0),
@@ -130,6 +155,9 @@ AudioFile::AudioFile(const std::string &filename) :
if (TagLib::MPEG::File *file = dynamic_cast<TagLib::MPEG::File*>(fileRef.file())) {
if (file->ID3v2Tag()) {
const TagLib::ID3v2::FrameListMap &map = file->ID3v2Tag()->frameListMap();
+ std::pair<unsigned int, unsigned int> discPair = extractTag<unsigned int, unsigned int>(map, "TPOS");
+ m_disc = discPair.first;
+ m_discTotal = discPair.second;
m_disc = extractTag<unsigned int>(map, "TPOS");
m_bpm = extractTag<unsigned int>(map, "TBPM");
m_composer = extractTag<std::string>(map, "TCOM");
@@ -141,6 +169,7 @@ AudioFile::AudioFile(const std::string &filename) :
if (file->tag()) {
const TagLib::Ogg::FieldListMap &map = file->tag()->fieldListMap();
m_disc = extractTag<unsigned int>(map, "DISCNUMBER");
+ m_discTotal = extractTag<unsigned int>(map, "DISCTOTAL");
m_bpm = extractTag<unsigned int>(map, "BPM");
m_composer = extractTag<std::string>(map, "COMPOSER");
m_compilation = extractTag<bool>(map, "COMPILATION");
@@ -149,6 +178,7 @@ AudioFile::AudioFile(const std::string &filename) :
if (file->xiphComment()) {
const TagLib::Ogg::FieldListMap &map = file->xiphComment()->fieldListMap();
m_disc = extractTag<unsigned int>(map, "DISCNUMBER");
+ m_discTotal = extractTag<unsigned int>(map, "DISCTOTAL");
m_bpm = extractTag<unsigned int>(map, "BPM");
m_composer = extractTag<std::string>(map, "COMPOSER");
m_compilation = extractTag<bool>(map, "COMPILATION");
@@ -156,7 +186,9 @@ AudioFile::AudioFile(const std::string &filename) :
} else if (TagLib::MP4::File *file = dynamic_cast<TagLib::MP4::File*>(fileRef.file())) {
if (file->tag()) {
const TagLib::MP4::ItemListMap &map = file->tag()->itemListMap();
- m_disc = extractTag<unsigned int>(map, "disk");
+ std::pair<unsigned int, unsigned int> discPair = extractTag<unsigned int, unsigned int>(map, "disk");
+ m_disc = discPair.first;
+ m_discTotal = discPair.second;
m_bpm = extractTag<unsigned int>(map, "tmpo");
m_albumArtist = extractTag<std::string>(map, "aART");
m_composer = extractTag<std::string>(map, "\xa9wrt");
diff --git a/AudioFile.h b/AudioFile.h
index 1fa4ce4..5450bfd 100644
--- a/AudioFile.h
+++ b/AudioFile.h
@@ -16,6 +16,7 @@ public:
inline std::string comment() const { return m_comment; };
inline unsigned int track() const { return m_track; };
inline unsigned int disc() const { return m_disc; };
+ inline unsigned int discTotal() const { return m_discTotal; };
inline unsigned int bpm() const { return m_bpm; };
inline unsigned int year() const { return m_year; };
inline unsigned int length() const { return m_length; };
@@ -38,6 +39,7 @@ private:
std::string m_comment;
unsigned int m_track;
unsigned int m_disc;
+ unsigned int m_discTotal;
unsigned int m_bpm;
unsigned int m_year;
unsigned int m_length;
diff --git a/organizemusic.cpp b/organizemusic.cpp
index 58612c0..9381485 100644
--- a/organizemusic.cpp
+++ b/organizemusic.cpp
@@ -59,9 +59,9 @@ string strip_slash(const string &name)
}
/* {disc}-{0-padded track}{space} with reasonable fallbacks. */
-void disc_track(unsigned int disc, unsigned int track, ostringstream &path)
+void disc_track(unsigned int disc, unsigned int discTotal, unsigned int track, ostringstream &path)
{
- if (disc > 0) {
+ if (discTotal != 1 && disc > 0) {
path << disc;
if (track > 0)
path << '-';
@@ -86,7 +86,7 @@ string generate_path(const AudioFile &audio)
path << "Unknown Album/";
else
path << strip_slash(audio.album()) << '/';
- disc_track(audio.disc(), audio.track(), path);
+ disc_track(audio.disc(), audio.discTotal(), audio.track(), path);
if (audio.artist().length() > 0)
path << strip_slash(audio.artist()) << " - ";
path << strip_slash(audio.title());
@@ -97,7 +97,7 @@ string generate_path(const AudioFile &audio)
path << strip_slash(audio.artist()) << '/';
if (audio.album().length() > 0)
path << strip_slash(audio.album()) << '/';
- disc_track(audio.disc(), audio.track(), path);
+ disc_track(audio.disc(), audio.discTotal(), audio.track(), path);
path << strip_slash(audio.title());
}
return transliterated(path.str());
diff --git a/readmusictags.cpp b/readmusictags.cpp
index 240c6b0..a9edfba 100644
--- a/readmusictags.cpp
+++ b/readmusictags.cpp
@@ -22,7 +22,7 @@ int main(int argc, char *argv[])
cout << setw(14) << "Genre: " << setw(0) << f.genre() << endl;
cout << setw(14) << "Comment: " << setw(0) << f.comment() << endl;
cout << setw(14) << "Track: " << setw(0) << f.track() << endl;
- cout << setw(14) << "Disc: " << setw(0) << f.disc() << endl;
+ cout << setw(14) << "Disc: " << setw(0) << f.disc() << '/' << f.discTotal() << endl;
cout << setw(14) << "Bpm: " << setw(0) << f.bpm() << endl;
cout << setw(14) << "Year: " << setw(0) << f.year() << endl;
cout << setw(14) << "Length: " << setw(0) << f.length() << endl;