Support play counter ID3v2 frame

This commit is contained in:
Martchus 2022-06-19 17:40:01 +02:00
parent 449ad034de
commit 0e3ccf8baa
5 changed files with 34 additions and 0 deletions

View File

@ -380,6 +380,10 @@ void Id3v2Frame::parse(BinaryReader &reader, std::uint32_t version, std::uint32_
// parse comment frame or unsynchronized lyrics frame (these two frame types have the same structure)
parseComment(buffer.get(), m_dataSize, value(), diag);
} else if (((version >= 3 && id() == Id3v2FrameIds::lPlayCounter) || (version < 3 && id() == Id3v2FrameIds::sPlayCounter))) {
// parse play counter frame
value().assignUnsignedInteger(readPlayCounter(buffer.get(), buffer.get() + m_dataSize, context, diag));
} else if (((version >= 3 && id() == Id3v2FrameIds::lRating) || (version < 3 && id() == Id3v2FrameIds::sRating))) {
// parse popularimeter frame
auto popularity = Popularity();
@ -697,6 +701,19 @@ Id3v2FrameMaker::Id3v2FrameMaker(Id3v2Frame &frame, std::uint8_t version, Diagno
// make comment frame or the unsynchronized lyrics frame
m_frame.makeComment(m_data, m_decompressedSize, *values.front(), version, diag);
} else if (((version >= 3 && m_frameId == Id3v2FrameIds::lPlayCounter) || (version < 3 && m_frameId == Id3v2FrameIds::sPlayCounter))) {
// make play counter frame
auto playCounter = std::uint64_t();
try {
playCounter = values.front()->toUnsignedInteger();
} catch (const ConversionException &) {
diag.emplace_back(DiagLevel::Warning,
argsToString("The play counter \"", values.front()->toDisplayString(), "\" is not an unsigned integer."), context);
}
m_decompressedSize = computePlayCounterSize(playCounter);
m_data = make_unique<char[]>(m_decompressedSize);
writePlayCounter(m_data.get() + m_decompressedSize - 1, m_decompressedSize, playCounter);
} else if (((version >= 3 && m_frameId == Id3v2FrameIds::lRating) || (version < 3 && m_frameId == Id3v2FrameIds::sRating))) {
// make popularimeter frame
auto popularity = Popularity();

View File

@ -79,6 +79,8 @@ std::uint32_t convertToShortId(std::uint32_t id)
return sRemixedBy;
case lCopyright:
return sCopyright;
case lPlayCounter:
return sPlayCounter;
case lRating:
return sRating;
case lISRC:
@ -147,6 +149,8 @@ std::uint32_t convertToLongId(std::uint32_t id)
return lRemixedBy;
case sCopyright:
return lCopyright;
case sPlayCounter:
return lPlayCounter;
case sRating:
return lRating;
case sISRC:

View File

@ -41,6 +41,7 @@ enum KnownValue : std::uint32_t {
lRecordLabel = 0x54505542, /**< TPUB \todo rename to lPublisher in v12 */
lUniqueFileId = 0x55464944, /**< UFID */
lComposer = 0x54434f4d, /**< TCOM */
lPlayCounter = 0x50434E54, /**< PCNT */
lRating = 0x504f504d, /**< POPM */
lRemixedBy = 0x54504534, /**< TPE4 */
lCopyright = 0x54434F50, /**< TCOP */
@ -75,6 +76,7 @@ enum KnownValue : std::uint32_t {
sRecordLabel = 0x545042, /**< ?TPB \todo rename to sPublisher in v12 */
sUniqueFileId = 0x554649, /**< ?UFI */
sComposer = 0x54434d, /**< ?TCM */
sPlayCounter = 0x434E54, /**< CNT */
sRating = 0x504f50, /**< ?POP */
sRemixedBy = 0x545034, /**< TP4 */
sCopyright = 0x544352, /**< TCR */

View File

@ -176,6 +176,8 @@ Id3v2Tag::IdentifierType Id3v2Tag::internallyGetFieldId(KnownField field) const
return lRecordLabel;
case KnownField::Composer:
return lComposer;
case KnownField::PlayCounter:
return lPlayCounter;
case KnownField::Rating:
return lRating;
case KnownField::AlbumArtist:
@ -236,6 +238,8 @@ Id3v2Tag::IdentifierType Id3v2Tag::internallyGetFieldId(KnownField field) const
return sRecordLabel;
case KnownField::Composer:
return sComposer;
case KnownField::PlayCounter:
return sPlayCounter;
case KnownField::Rating:
return sRating;
case KnownField::AlbumArtist:
@ -307,6 +311,8 @@ KnownField Id3v2Tag::internallyGetKnownField(const IdentifierType &id) const
return KnownField::OriginalReleaseDate;
case lMood:
return KnownField::Mood;
case lPlayCounter:
return KnownField::PlayCounter;
case lRating:
return KnownField::Rating;
case lISRC:
@ -351,6 +357,8 @@ KnownField Id3v2Tag::internallyGetKnownField(const IdentifierType &id) const
return KnownField::RemixedBy;
case sCopyright:
return KnownField::Copyright;
case sPlayCounter:
return KnownField::PlayCounter;
case sRating:
return KnownField::Rating;
case sISRC:
@ -371,6 +379,8 @@ TagDataType Id3v2Tag::internallyGetProposedDataType(const std::uint32_t &id) con
case sBpm:
case lYear:
case sYear:
case lPlayCounter:
case sPlayCounter:
return TagDataType::Integer;
case lTrackPosition:
case sTrackPosition:

1
tag.h
View File

@ -293,6 +293,7 @@ inline TagDataType Tag::proposedDataType(KnownField field) const
case KnownField::Bps:
case KnownField::PartNumber:
case KnownField::TotalParts:
case KnownField::PlayCounter:
return TagDataType::Integer;
case KnownField::Cover:
return TagDataType::Picture;