Support album artist and fix/improve grouping
This commit is contained in:
parent
f1382bd286
commit
6afcd0f8d3
|
@ -179,8 +179,8 @@ set(META_APP_AUTHOR "Martchus")
|
||||||
set(META_APP_URL "https://github.com/${META_APP_AUTHOR}/${META_PROJECT_NAME}")
|
set(META_APP_URL "https://github.com/${META_APP_AUTHOR}/${META_PROJECT_NAME}")
|
||||||
set(META_APP_DESCRIPTION "C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags")
|
set(META_APP_DESCRIPTION "C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags")
|
||||||
set(META_VERSION_MAJOR 8)
|
set(META_VERSION_MAJOR 8)
|
||||||
set(META_VERSION_MINOR 0)
|
set(META_VERSION_MINOR 1)
|
||||||
set(META_VERSION_PATCH 2)
|
set(META_VERSION_PATCH 0)
|
||||||
set(META_PUBLIC_SHARED_LIB_DEPENDS c++utilities)
|
set(META_PUBLIC_SHARED_LIB_DEPENDS c++utilities)
|
||||||
set(META_PUBLIC_STATIC_LIB_DEPENDS c++utilities_static)
|
set(META_PUBLIC_STATIC_LIB_DEPENDS c++utilities_static)
|
||||||
set(META_REQUIRED_CPP_UNIT_VERSION 1.14.0)
|
set(META_REQUIRED_CPP_UNIT_VERSION 1.14.0)
|
||||||
|
|
|
@ -59,6 +59,8 @@ uint32 convertToShortId(uint32 id)
|
||||||
return sUnsynchronizedLyrics;
|
return sUnsynchronizedLyrics;
|
||||||
case lGrouping:
|
case lGrouping:
|
||||||
return sGrouping;
|
return sGrouping;
|
||||||
|
case lContentGroupDescription:
|
||||||
|
return sContentGroupDescription;
|
||||||
case lRecordLabel:
|
case lRecordLabel:
|
||||||
return sRecordLabel;
|
return sRecordLabel;
|
||||||
case lUserDefinedText:
|
case lUserDefinedText:
|
||||||
|
@ -111,6 +113,8 @@ uint32 convertToLongId(uint32 id)
|
||||||
return lUnsynchronizedLyrics;
|
return lUnsynchronizedLyrics;
|
||||||
case sGrouping:
|
case sGrouping:
|
||||||
return lGrouping;
|
return lGrouping;
|
||||||
|
case sContentGroupDescription:
|
||||||
|
return lContentGroupDescription;
|
||||||
case sRecordLabel:
|
case sRecordLabel:
|
||||||
return lRecordLabel;
|
return lRecordLabel;
|
||||||
case sUserDefinedText:
|
case sUserDefinedText:
|
||||||
|
|
|
@ -27,7 +27,8 @@ enum KnownValue : uint32 {
|
||||||
lEncoderSettings = 0x54535345,
|
lEncoderSettings = 0x54535345,
|
||||||
lUnsynchronizedLyrics = 0x55534c54,
|
lUnsynchronizedLyrics = 0x55534c54,
|
||||||
lSynchronizedLyrics = 0x53594C54,
|
lSynchronizedLyrics = 0x53594C54,
|
||||||
lGrouping = 0x54504532,
|
lGrouping = 0x54504532, // FIXME: rename to lAlbumArtist in v9
|
||||||
|
lContentGroupDescription = 0x54495431,
|
||||||
lRecordLabel = 0x54505542,
|
lRecordLabel = 0x54505542,
|
||||||
lUniqueFileId = 0x55464944,
|
lUniqueFileId = 0x55464944,
|
||||||
lComposer = 0x54434f4d,
|
lComposer = 0x54434f4d,
|
||||||
|
@ -52,7 +53,8 @@ enum KnownValue : uint32 {
|
||||||
sEncoderSettings = 0x545353,
|
sEncoderSettings = 0x545353,
|
||||||
sUnsynchronizedLyrics = 0x554C54,
|
sUnsynchronizedLyrics = 0x554C54,
|
||||||
sSynchronizedLyrics = 0x534C54,
|
sSynchronizedLyrics = 0x534C54,
|
||||||
sGrouping = 0x545032,
|
sGrouping = 0x545032, // FIXME: rename to sAlbumArtist in v9
|
||||||
|
sContentGroupDescription = 0x545431,
|
||||||
sRecordLabel = 0x545042,
|
sRecordLabel = 0x545042,
|
||||||
sUniqueFileId = 0x554649,
|
sUniqueFileId = 0x554649,
|
||||||
sComposer = 0x54434d,
|
sComposer = 0x54434d,
|
||||||
|
|
|
@ -44,6 +44,7 @@ bool Id3v2Tag::supportsMultipleValues(KnownField field) const
|
||||||
case KnownField::Grouping:
|
case KnownField::Grouping:
|
||||||
case KnownField::RecordLabel:
|
case KnownField::RecordLabel:
|
||||||
case KnownField::Composer:
|
case KnownField::Composer:
|
||||||
|
case KnownField::AlbumArtist:
|
||||||
return m_majorVersion > 3;
|
return m_majorVersion > 3;
|
||||||
case KnownField::Rating:
|
case KnownField::Rating:
|
||||||
case KnownField::Comment:
|
case KnownField::Comment:
|
||||||
|
@ -166,13 +167,15 @@ Id3v2Tag::IdentifierType Id3v2Tag::internallyGetFieldId(KnownField field) const
|
||||||
case KnownField::SynchronizedLyrics:
|
case KnownField::SynchronizedLyrics:
|
||||||
return lSynchronizedLyrics;
|
return lSynchronizedLyrics;
|
||||||
case KnownField::Grouping:
|
case KnownField::Grouping:
|
||||||
return lGrouping;
|
return lContentGroupDescription;
|
||||||
case KnownField::RecordLabel:
|
case KnownField::RecordLabel:
|
||||||
return lRecordLabel;
|
return lRecordLabel;
|
||||||
case KnownField::Composer:
|
case KnownField::Composer:
|
||||||
return lComposer;
|
return lComposer;
|
||||||
case KnownField::Rating:
|
case KnownField::Rating:
|
||||||
return lRating;
|
return lRating;
|
||||||
|
case KnownField::AlbumArtist:
|
||||||
|
return lGrouping;
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -214,13 +217,15 @@ Id3v2Tag::IdentifierType Id3v2Tag::internallyGetFieldId(KnownField field) const
|
||||||
case KnownField::SynchronizedLyrics:
|
case KnownField::SynchronizedLyrics:
|
||||||
return sSynchronizedLyrics;
|
return sSynchronizedLyrics;
|
||||||
case KnownField::Grouping:
|
case KnownField::Grouping:
|
||||||
return sGrouping;
|
return sContentGroupDescription;
|
||||||
case KnownField::RecordLabel:
|
case KnownField::RecordLabel:
|
||||||
return sRecordLabel;
|
return sRecordLabel;
|
||||||
case KnownField::Composer:
|
case KnownField::Composer:
|
||||||
return sComposer;
|
return sComposer;
|
||||||
case KnownField::Rating:
|
case KnownField::Rating:
|
||||||
return sRating;
|
return sRating;
|
||||||
|
case KnownField::AlbumArtist:
|
||||||
|
return sGrouping;
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -268,6 +273,8 @@ KnownField Id3v2Tag::internallyGetKnownField(const IdentifierType &id) const
|
||||||
case lSynchronizedLyrics:
|
case lSynchronizedLyrics:
|
||||||
return KnownField::SynchronizedLyrics;
|
return KnownField::SynchronizedLyrics;
|
||||||
case lGrouping:
|
case lGrouping:
|
||||||
|
return KnownField::AlbumArtist;
|
||||||
|
case lContentGroupDescription:
|
||||||
return KnownField::Grouping;
|
return KnownField::Grouping;
|
||||||
case lRecordLabel:
|
case lRecordLabel:
|
||||||
return KnownField::RecordLabel;
|
return KnownField::RecordLabel;
|
||||||
|
|
|
@ -159,6 +159,8 @@ Mp4Tag::IdentifierType Mp4Tag::internallyGetFieldId(KnownField field) const
|
||||||
return Performers;
|
return Performers;
|
||||||
case KnownField::Lyricist:
|
case KnownField::Lyricist:
|
||||||
return Lyricist;
|
return Lyricist;
|
||||||
|
case KnownField::AlbumArtist:
|
||||||
|
return AlbumArtist;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -207,6 +209,8 @@ KnownField Mp4Tag::internallyGetKnownField(const IdentifierType &id) const
|
||||||
return KnownField::Performers;
|
return KnownField::Performers;
|
||||||
case Lyricist:
|
case Lyricist:
|
||||||
return KnownField::Lyricist;
|
return KnownField::Lyricist;
|
||||||
|
case AlbumArtist:
|
||||||
|
return KnownField::AlbumArtist;
|
||||||
default:
|
default:
|
||||||
return KnownField::Invalid;
|
return KnownField::Invalid;
|
||||||
}
|
}
|
||||||
|
|
5
tag.h
5
tag.h
|
@ -35,6 +35,8 @@ enum class TagType : unsigned int {
|
||||||
*
|
*
|
||||||
* Not all fields are supported by all tag types (see Tag::supportsField()).
|
* Not all fields are supported by all tag types (see Tag::supportsField()).
|
||||||
*
|
*
|
||||||
|
* Mapping proposed by HAK: https://wiki.hydrogenaud.io/index.php?title=Tag_Mapping
|
||||||
|
*
|
||||||
* \sa Tag::type()
|
* \sa Tag::type()
|
||||||
*/
|
*/
|
||||||
enum class KnownField : unsigned int {
|
enum class KnownField : unsigned int {
|
||||||
|
@ -66,7 +68,8 @@ enum class KnownField : unsigned int {
|
||||||
Composer, /**< composer */
|
Composer, /**< composer */
|
||||||
Rating, /**< rating */
|
Rating, /**< rating */
|
||||||
Description, /**< description */
|
Description, /**< description */
|
||||||
Vendor /**< vendor */
|
Vendor, /**< vendor */
|
||||||
|
AlbumArtist, /**< album artist */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -77,6 +77,8 @@ VorbisComment::IdentifierType VorbisComment::internallyGetFieldId(KnownField fie
|
||||||
return encoderSettings();
|
return encoderSettings();
|
||||||
case KnownField::Description:
|
case KnownField::Description:
|
||||||
return description();
|
return description();
|
||||||
|
case KnownField::Grouping:
|
||||||
|
return grouping();
|
||||||
case KnownField::RecordLabel:
|
case KnownField::RecordLabel:
|
||||||
return label();
|
return label();
|
||||||
case KnownField::Performers:
|
case KnownField::Performers:
|
||||||
|
@ -85,6 +87,8 @@ VorbisComment::IdentifierType VorbisComment::internallyGetFieldId(KnownField fie
|
||||||
return language();
|
return language();
|
||||||
case KnownField::Lyricist:
|
case KnownField::Lyricist:
|
||||||
return lyricist();
|
return lyricist();
|
||||||
|
case KnownField::AlbumArtist:
|
||||||
|
return albumArtist();
|
||||||
default:
|
default:
|
||||||
return string();
|
return string();
|
||||||
}
|
}
|
||||||
|
@ -93,12 +97,29 @@ VorbisComment::IdentifierType VorbisComment::internallyGetFieldId(KnownField fie
|
||||||
KnownField VorbisComment::internallyGetKnownField(const IdentifierType &id) const
|
KnownField VorbisComment::internallyGetKnownField(const IdentifierType &id) const
|
||||||
{
|
{
|
||||||
using namespace VorbisCommentIds;
|
using namespace VorbisCommentIds;
|
||||||
static const map<string, KnownField, CaseInsensitiveStringComparer> fieldMap({ { album(), KnownField::Album }, { artist(), KnownField::Artist },
|
// clang-format off
|
||||||
{ comment(), KnownField::Comment }, { cover(), KnownField::Cover }, { date(), KnownField::Year }, { title(), KnownField::Title },
|
static const map<string, KnownField, CaseInsensitiveStringComparer> fieldMap({
|
||||||
{ genre(), KnownField::Genre }, { trackNumber(), KnownField::TrackPosition }, { diskNumber(), KnownField::DiskPosition },
|
{ album(), KnownField::Album },
|
||||||
{ partNumber(), KnownField::PartNumber }, { composer(), KnownField::Composer }, { encoder(), KnownField::Encoder },
|
{ artist(), KnownField::Artist },
|
||||||
{ encoderSettings(), KnownField::EncoderSettings }, { description(), KnownField::Description }, { label(), KnownField::RecordLabel },
|
{ comment(), KnownField::Comment },
|
||||||
{ performer(), KnownField::Performers }, { lyricist(), KnownField::Lyricist } });
|
{ cover(), KnownField::Cover },
|
||||||
|
{ date(), KnownField::Year },
|
||||||
|
{ title(), KnownField::Title },
|
||||||
|
{ genre(), KnownField::Genre },
|
||||||
|
{ trackNumber(), KnownField::TrackPosition },
|
||||||
|
{ diskNumber(), KnownField::DiskPosition },
|
||||||
|
{ partNumber(), KnownField::PartNumber },
|
||||||
|
{ composer(), KnownField::Composer },
|
||||||
|
{ encoder(), KnownField::Encoder },
|
||||||
|
{ encoderSettings(), KnownField::EncoderSettings },
|
||||||
|
{ description(), KnownField::Description },
|
||||||
|
{ grouping(), KnownField::Grouping },
|
||||||
|
{ label(), KnownField::RecordLabel },
|
||||||
|
{ performer(), KnownField::Performers },
|
||||||
|
{ lyricist(), KnownField::Lyricist },
|
||||||
|
{ albumArtist(), KnownField::AlbumArtist },
|
||||||
|
});
|
||||||
|
// clang-format on
|
||||||
const auto knownField(fieldMap.find(id));
|
const auto knownField(fieldMap.find(id));
|
||||||
return knownField != fieldMap.cend() ? knownField->second : KnownField::Invalid;
|
return knownField != fieldMap.cend() ? knownField->second : KnownField::Invalid;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,14 @@ constexpr TAG_PARSER_EXPORT const char *artist()
|
||||||
{
|
{
|
||||||
return "ARTIST";
|
return "ARTIST";
|
||||||
}
|
}
|
||||||
|
constexpr TAG_PARSER_EXPORT const char *albumArtist()
|
||||||
|
{
|
||||||
|
return "ALBUMARTIST";
|
||||||
|
}
|
||||||
|
constexpr TAG_PARSER_EXPORT const char *grouping()
|
||||||
|
{
|
||||||
|
return "GROUPING";
|
||||||
|
}
|
||||||
constexpr TAG_PARSER_EXPORT const char *album()
|
constexpr TAG_PARSER_EXPORT const char *album()
|
||||||
{
|
{
|
||||||
return "ALBUM";
|
return "ALBUM";
|
||||||
|
|
Loading…
Reference in New Issue