From baf66899f53f176378fa7dfe7ff78f676e627307 Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Wed, 22 Aug 2012 19:17:54 +0200 Subject: Extract disc total and utilize that too. --- AudioFile.cpp | 36 ++++++++++++++++++++++++++++++++++-- AudioFile.h | 2 ++ organizemusic.cpp | 8 ++++---- readmusictags.cpp | 2 +- 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 inline T extractTag(M &map, const char *key) { T ret = 0; - std::stringstream stream(extractTag(map, key)); + std::istringstream stream(extractTag(map, key)); stream >> ret; return ret; } +/* Turn a string into a pair of integer types separated by a slash + * for any map class. */ +template +inline std::pair extractTag(M &map, const char *key) +{ + std::pair values; + values.first = 0; + values.second = 0; + char slash = '\0'; + std::istringstream stream(extractTag(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 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 +inline std::pair extractTag(const TagLib::MP4::ItemListMap &map, const char *key) +{ + if (!map[key].isValid()) + return std::pair(0, 0); + TagLib::MP4::Item::IntPair pair = map[key].toIntPair(); + return std::pair(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(fileRef.file())) { if (file->ID3v2Tag()) { const TagLib::ID3v2::FrameListMap &map = file->ID3v2Tag()->frameListMap(); + std::pair discPair = extractTag(map, "TPOS"); + m_disc = discPair.first; + m_discTotal = discPair.second; m_disc = extractTag(map, "TPOS"); m_bpm = extractTag(map, "TBPM"); m_composer = extractTag(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(map, "DISCNUMBER"); + m_discTotal = extractTag(map, "DISCTOTAL"); m_bpm = extractTag(map, "BPM"); m_composer = extractTag(map, "COMPOSER"); m_compilation = extractTag(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(map, "DISCNUMBER"); + m_discTotal = extractTag(map, "DISCTOTAL"); m_bpm = extractTag(map, "BPM"); m_composer = extractTag(map, "COMPOSER"); m_compilation = extractTag(map, "COMPILATION"); @@ -156,7 +186,9 @@ AudioFile::AudioFile(const std::string &filename) : } else if (TagLib::MP4::File *file = dynamic_cast(fileRef.file())) { if (file->tag()) { const TagLib::MP4::ItemListMap &map = file->tag()->itemListMap(); - m_disc = extractTag(map, "disk"); + std::pair discPair = extractTag(map, "disk"); + m_disc = discPair.first; + m_discTotal = discPair.second; m_bpm = extractTag(map, "tmpo"); m_albumArtist = extractTag(map, "aART"); m_composer = extractTag(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; -- cgit v1.2.3-59-g8ed1b