Format taglib sources
This commit is contained in:
142
3rdparty/taglib/mpc/mpcfile.cpp
vendored
142
3rdparty/taglib/mpc/mpcfile.cpp
vendored
@@ -38,25 +38,22 @@
|
||||
|
||||
using namespace Strawberry_TagLib::TagLib;
|
||||
|
||||
namespace
|
||||
{
|
||||
enum { MPCAPEIndex = 0, MPCID3v1Index = 1 };
|
||||
namespace {
|
||||
enum { MPCAPEIndex = 0,
|
||||
MPCID3v1Index = 1 };
|
||||
}
|
||||
|
||||
class MPC::File::FilePrivate
|
||||
{
|
||||
public:
|
||||
FilePrivate() :
|
||||
APELocation(-1),
|
||||
APESize(0),
|
||||
ID3v1Location(-1),
|
||||
ID3v2Header(0),
|
||||
ID3v2Location(-1),
|
||||
ID3v2Size(0),
|
||||
properties(0) {}
|
||||
class MPC::File::FilePrivate {
|
||||
public:
|
||||
FilePrivate() : APELocation(-1),
|
||||
APESize(0),
|
||||
ID3v1Location(-1),
|
||||
ID3v2Header(0),
|
||||
ID3v2Location(-1),
|
||||
ID3v2Size(0),
|
||||
properties(0) {}
|
||||
|
||||
~FilePrivate()
|
||||
{
|
||||
~FilePrivate() {
|
||||
delete ID3v2Header;
|
||||
delete properties;
|
||||
}
|
||||
@@ -79,8 +76,7 @@ public:
|
||||
// static members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool MPC::File::isSupported(IOStream *stream)
|
||||
{
|
||||
bool MPC::File::isSupported(IOStream *stream) {
|
||||
// A newer MPC file has to start with "MPCK" or "MP+", but older files don't
|
||||
// have keys to do a quick check.
|
||||
|
||||
@@ -92,71 +88,60 @@ bool MPC::File::isSupported(IOStream *stream)
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
MPC::File::File(FileName file, bool readProperties, Properties::ReadStyle) :
|
||||
Strawberry_TagLib::TagLib::File(file),
|
||||
d(new FilePrivate())
|
||||
{
|
||||
if(isOpen())
|
||||
MPC::File::File(FileName file, bool readProperties, Properties::ReadStyle) : Strawberry_TagLib::TagLib::File(file),
|
||||
d(new FilePrivate()) {
|
||||
if (isOpen())
|
||||
read(readProperties);
|
||||
}
|
||||
|
||||
MPC::File::File(IOStream *stream, bool readProperties, Properties::ReadStyle) :
|
||||
Strawberry_TagLib::TagLib::File(stream),
|
||||
d(new FilePrivate())
|
||||
{
|
||||
if(isOpen())
|
||||
MPC::File::File(IOStream *stream, bool readProperties, Properties::ReadStyle) : Strawberry_TagLib::TagLib::File(stream),
|
||||
d(new FilePrivate()) {
|
||||
if (isOpen())
|
||||
read(readProperties);
|
||||
}
|
||||
|
||||
MPC::File::~File()
|
||||
{
|
||||
MPC::File::~File() {
|
||||
delete d;
|
||||
}
|
||||
|
||||
Strawberry_TagLib::TagLib::Tag *MPC::File::tag() const
|
||||
{
|
||||
Strawberry_TagLib::TagLib::Tag *MPC::File::tag() const {
|
||||
return &d->tag;
|
||||
}
|
||||
|
||||
PropertyMap MPC::File::properties() const
|
||||
{
|
||||
PropertyMap MPC::File::properties() const {
|
||||
return d->tag.properties();
|
||||
}
|
||||
|
||||
void MPC::File::removeUnsupportedProperties(const StringList &properties)
|
||||
{
|
||||
void MPC::File::removeUnsupportedProperties(const StringList &properties) {
|
||||
d->tag.removeUnsupportedProperties(properties);
|
||||
}
|
||||
|
||||
PropertyMap MPC::File::setProperties(const PropertyMap &properties)
|
||||
{
|
||||
if(ID3v1Tag())
|
||||
PropertyMap MPC::File::setProperties(const PropertyMap &properties) {
|
||||
if (ID3v1Tag())
|
||||
ID3v1Tag()->setProperties(properties);
|
||||
|
||||
return APETag(true)->setProperties(properties);
|
||||
}
|
||||
|
||||
MPC::Properties *MPC::File::audioProperties() const
|
||||
{
|
||||
MPC::Properties *MPC::File::audioProperties() const {
|
||||
return d->properties;
|
||||
}
|
||||
|
||||
bool MPC::File::save()
|
||||
{
|
||||
if(readOnly()) {
|
||||
bool MPC::File::save() {
|
||||
if (readOnly()) {
|
||||
debug("MPC::File::save() -- File is read only.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Possibly strip ID3v2 tag
|
||||
|
||||
if(!d->ID3v2Header && d->ID3v2Location >= 0) {
|
||||
if (!d->ID3v2Header && d->ID3v2Location >= 0) {
|
||||
removeBlock(d->ID3v2Location, d->ID3v2Size);
|
||||
|
||||
if(d->APELocation >= 0)
|
||||
if (d->APELocation >= 0)
|
||||
d->APELocation -= d->ID3v2Size;
|
||||
|
||||
if(d->ID3v1Location >= 0)
|
||||
if (d->ID3v1Location >= 0)
|
||||
d->ID3v1Location -= d->ID3v2Size;
|
||||
|
||||
d->ID3v2Location = -1;
|
||||
@@ -165,11 +150,11 @@ bool MPC::File::save()
|
||||
|
||||
// Update ID3v1 tag
|
||||
|
||||
if(ID3v1Tag() && !ID3v1Tag()->isEmpty()) {
|
||||
if (ID3v1Tag() && !ID3v1Tag()->isEmpty()) {
|
||||
|
||||
// ID3v1 tag is not empty. Update the old one or create a new one.
|
||||
|
||||
if(d->ID3v1Location >= 0) {
|
||||
if (d->ID3v1Location >= 0) {
|
||||
seek(d->ID3v1Location);
|
||||
}
|
||||
else {
|
||||
@@ -183,7 +168,7 @@ bool MPC::File::save()
|
||||
|
||||
// ID3v1 tag is empty. Remove the old one.
|
||||
|
||||
if(d->ID3v1Location >= 0) {
|
||||
if (d->ID3v1Location >= 0) {
|
||||
truncate(d->ID3v1Location);
|
||||
d->ID3v1Location = -1;
|
||||
}
|
||||
@@ -191,12 +176,12 @@ bool MPC::File::save()
|
||||
|
||||
// Update APE tag
|
||||
|
||||
if(APETag() && !APETag()->isEmpty()) {
|
||||
if (APETag() && !APETag()->isEmpty()) {
|
||||
|
||||
// APE tag is not empty. Update the old one or create a new one.
|
||||
|
||||
if(d->APELocation < 0) {
|
||||
if(d->ID3v1Location >= 0)
|
||||
if (d->APELocation < 0) {
|
||||
if (d->ID3v1Location >= 0)
|
||||
d->APELocation = d->ID3v1Location;
|
||||
else
|
||||
d->APELocation = length();
|
||||
@@ -205,7 +190,7 @@ bool MPC::File::save()
|
||||
const ByteVector data = APETag()->render();
|
||||
insert(data, d->APELocation, d->APESize);
|
||||
|
||||
if(d->ID3v1Location >= 0)
|
||||
if (d->ID3v1Location >= 0)
|
||||
d->ID3v1Location += (static_cast<long>(data.size()) - d->APESize);
|
||||
|
||||
d->APESize = data.size();
|
||||
@@ -214,10 +199,10 @@ bool MPC::File::save()
|
||||
|
||||
// APE tag is empty. Remove the old one.
|
||||
|
||||
if(d->APELocation >= 0) {
|
||||
if (d->APELocation >= 0) {
|
||||
removeBlock(d->APELocation, d->APESize);
|
||||
|
||||
if(d->ID3v1Location >= 0)
|
||||
if (d->ID3v1Location >= 0)
|
||||
d->ID3v1Location -= d->APESize;
|
||||
|
||||
d->APELocation = -1;
|
||||
@@ -228,45 +213,39 @@ bool MPC::File::save()
|
||||
return true;
|
||||
}
|
||||
|
||||
ID3v1::Tag *MPC::File::ID3v1Tag(bool create)
|
||||
{
|
||||
ID3v1::Tag *MPC::File::ID3v1Tag(bool create) {
|
||||
return d->tag.access<ID3v1::Tag>(MPCID3v1Index, create);
|
||||
}
|
||||
|
||||
APE::Tag *MPC::File::APETag(bool create)
|
||||
{
|
||||
APE::Tag *MPC::File::APETag(bool create) {
|
||||
return d->tag.access<APE::Tag>(MPCAPEIndex, create);
|
||||
}
|
||||
|
||||
void MPC::File::strip(int tags)
|
||||
{
|
||||
if(tags & ID3v1)
|
||||
void MPC::File::strip(int tags) {
|
||||
if (tags & ID3v1)
|
||||
d->tag.set(MPCID3v1Index, 0);
|
||||
|
||||
if(tags & APE)
|
||||
if (tags & APE)
|
||||
d->tag.set(MPCAPEIndex, 0);
|
||||
|
||||
if(!ID3v1Tag())
|
||||
if (!ID3v1Tag())
|
||||
APETag(true);
|
||||
|
||||
if(tags & ID3v2) {
|
||||
if (tags & ID3v2) {
|
||||
delete d->ID3v2Header;
|
||||
d->ID3v2Header = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void MPC::File::remove(int tags)
|
||||
{
|
||||
void MPC::File::remove(int tags) {
|
||||
strip(tags);
|
||||
}
|
||||
|
||||
bool MPC::File::hasID3v1Tag() const
|
||||
{
|
||||
bool MPC::File::hasID3v1Tag() const {
|
||||
return (d->ID3v1Location >= 0);
|
||||
}
|
||||
|
||||
bool MPC::File::hasAPETag() const
|
||||
{
|
||||
bool MPC::File::hasAPETag() const {
|
||||
return (d->APELocation >= 0);
|
||||
}
|
||||
|
||||
@@ -274,13 +253,12 @@ bool MPC::File::hasAPETag() const
|
||||
// private members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void MPC::File::read(bool readProperties)
|
||||
{
|
||||
void MPC::File::read(bool readProperties) {
|
||||
// Look for an ID3v2 tag
|
||||
|
||||
d->ID3v2Location = Utils::findID3v2(this);
|
||||
|
||||
if(d->ID3v2Location >= 0) {
|
||||
if (d->ID3v2Location >= 0) {
|
||||
seek(d->ID3v2Location);
|
||||
d->ID3v2Header = new ID3v2::Header(readBlock(ID3v2::Header::size()));
|
||||
d->ID3v2Size = d->ID3v2Header->completeTagSize();
|
||||
@@ -290,36 +268,36 @@ void MPC::File::read(bool readProperties)
|
||||
|
||||
d->ID3v1Location = Utils::findID3v1(this);
|
||||
|
||||
if(d->ID3v1Location >= 0)
|
||||
if (d->ID3v1Location >= 0)
|
||||
d->tag.set(MPCID3v1Index, new ID3v1::Tag(this, d->ID3v1Location));
|
||||
|
||||
// Look for an APE tag
|
||||
|
||||
d->APELocation = Utils::findAPE(this, d->ID3v1Location);
|
||||
|
||||
if(d->APELocation >= 0) {
|
||||
if (d->APELocation >= 0) {
|
||||
d->tag.set(MPCAPEIndex, new APE::Tag(this, d->APELocation));
|
||||
d->APESize = APETag()->footer()->completeTagSize();
|
||||
d->APELocation = d->APELocation + APE::Footer::size() - d->APESize;
|
||||
}
|
||||
|
||||
if(d->ID3v1Location < 0)
|
||||
if (d->ID3v1Location < 0)
|
||||
APETag(true);
|
||||
|
||||
// Look for MPC metadata
|
||||
|
||||
if(readProperties) {
|
||||
if (readProperties) {
|
||||
|
||||
long streamLength;
|
||||
|
||||
if(d->APELocation >= 0)
|
||||
if (d->APELocation >= 0)
|
||||
streamLength = d->APELocation;
|
||||
else if(d->ID3v1Location >= 0)
|
||||
else if (d->ID3v1Location >= 0)
|
||||
streamLength = d->ID3v1Location;
|
||||
else
|
||||
streamLength = length();
|
||||
|
||||
if(d->ID3v2Location >= 0) {
|
||||
if (d->ID3v2Location >= 0) {
|
||||
seek(d->ID3v2Location + d->ID3v2Size);
|
||||
streamLength -= (d->ID3v2Location + d->ID3v2Size);
|
||||
}
|
||||
|
||||
137
3rdparty/taglib/mpc/mpcfile.h
vendored
137
3rdparty/taglib/mpc/mpcfile.h
vendored
@@ -37,14 +37,18 @@
|
||||
namespace Strawberry_TagLib {
|
||||
namespace TagLib {
|
||||
|
||||
class Tag;
|
||||
class Tag;
|
||||
|
||||
namespace ID3v1 { class Tag; }
|
||||
namespace APE { class Tag; }
|
||||
namespace ID3v1 {
|
||||
class Tag;
|
||||
}
|
||||
namespace APE {
|
||||
class Tag;
|
||||
}
|
||||
|
||||
//! An implementation of MPC metadata
|
||||
//! An implementation of MPC metadata
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* This is implementation of MPC metadata.
|
||||
*
|
||||
* This supports ID3v1 and APE (v1 and v2) style comments as well as reading stream
|
||||
@@ -52,11 +56,11 @@ namespace TagLib {
|
||||
* and ignored.
|
||||
*/
|
||||
|
||||
namespace MPC {
|
||||
namespace MPC {
|
||||
|
||||
//! An implementation of TagLib::File with MPC specific methods
|
||||
//! An implementation of TagLib::File with MPC specific methods
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* This implements and provides an interface for MPC files to the
|
||||
* TagLib::Tag and TagLib::AudioProperties interfaces by way of implementing
|
||||
* the abstract TagLib::File API as well as providing some additional
|
||||
@@ -64,36 +68,35 @@ namespace TagLib {
|
||||
* The only invalid tag combination supported is an ID3v1 tag after an APE tag.
|
||||
*/
|
||||
|
||||
class TAGLIB_EXPORT File : public Strawberry_TagLib::TagLib::File
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
class TAGLIB_EXPORT File : public Strawberry_TagLib::TagLib::File {
|
||||
public:
|
||||
/*!
|
||||
* This set of flags is used for various operations and is suitable for
|
||||
* being OR-ed together.
|
||||
*/
|
||||
enum TagTypes {
|
||||
//! Empty set. Matches no tag types.
|
||||
NoTags = 0x0000,
|
||||
//! Matches ID3v1 tags.
|
||||
ID3v1 = 0x0001,
|
||||
//! Matches ID3v2 tags.
|
||||
ID3v2 = 0x0002,
|
||||
//! Matches APE tags.
|
||||
APE = 0x0004,
|
||||
//! Matches all tag types.
|
||||
AllTags = 0xffff
|
||||
};
|
||||
enum TagTypes {
|
||||
//! Empty set. Matches no tag types.
|
||||
NoTags = 0x0000,
|
||||
//! Matches ID3v1 tags.
|
||||
ID3v1 = 0x0001,
|
||||
//! Matches ID3v2 tags.
|
||||
ID3v2 = 0x0002,
|
||||
//! Matches APE tags.
|
||||
APE = 0x0004,
|
||||
//! Matches all tag types.
|
||||
AllTags = 0xffff
|
||||
};
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Constructs an MPC file from \a file. If \a readProperties is true the
|
||||
* file's audio properties will also be read.
|
||||
*
|
||||
* \note In the current implementation, \a propertiesStyle is ignored.
|
||||
*/
|
||||
File(FileName file, bool readProperties = true,
|
||||
Properties::ReadStyle propertiesStyle = Properties::Average);
|
||||
File(FileName file, bool readProperties = true,
|
||||
Properties::ReadStyle propertiesStyle = Properties::Average);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Constructs an MPC file from \a stream. If \a readProperties is true the
|
||||
* file's audio properties will also be read.
|
||||
*
|
||||
@@ -102,50 +105,50 @@ namespace TagLib {
|
||||
*
|
||||
* \note In the current implementation, \a propertiesStyle is ignored.
|
||||
*/
|
||||
File(IOStream *stream, bool readProperties = true,
|
||||
Properties::ReadStyle propertiesStyle = Properties::Average);
|
||||
File(IOStream *stream, bool readProperties = true,
|
||||
Properties::ReadStyle propertiesStyle = Properties::Average);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Destroys this instance of the File.
|
||||
*/
|
||||
virtual ~File();
|
||||
virtual ~File();
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns the Tag for this file. This will be an APE tag, an ID3v1 tag
|
||||
* or a combination of the two.
|
||||
*/
|
||||
virtual Strawberry_TagLib::TagLib::Tag *tag() const;
|
||||
virtual Strawberry_TagLib::TagLib::Tag *tag() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Implements the unified property interface -- export function.
|
||||
* If the file contains both an APE and an ID3v1 tag, only the APE
|
||||
* tag will be converted to the PropertyMap.
|
||||
*/
|
||||
PropertyMap properties() const;
|
||||
PropertyMap properties() const;
|
||||
|
||||
void removeUnsupportedProperties(const StringList &properties);
|
||||
void removeUnsupportedProperties(const StringList &properties);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Implements the unified property interface -- import function.
|
||||
* Affects only the APEv2 tag which will be created if necessary.
|
||||
* If an ID3v1 tag exists, it will be updated as well.
|
||||
*/
|
||||
PropertyMap setProperties(const PropertyMap &);
|
||||
PropertyMap setProperties(const PropertyMap &);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns the MPC::Properties for this file. If no audio properties
|
||||
* were read then this will return a null pointer.
|
||||
*/
|
||||
virtual Properties *audioProperties() const;
|
||||
virtual Properties *audioProperties() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Saves the file.
|
||||
*
|
||||
* This returns true if the save was successful.
|
||||
*/
|
||||
virtual bool save();
|
||||
virtual bool save();
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns a pointer to the ID3v1 tag of the file.
|
||||
*
|
||||
* If \a create is false (the default) this returns a null pointer
|
||||
@@ -162,9 +165,9 @@ namespace TagLib {
|
||||
*
|
||||
* \see hasID3v1Tag()
|
||||
*/
|
||||
ID3v1::Tag *ID3v1Tag(bool create = false);
|
||||
ID3v1::Tag *ID3v1Tag(bool create = false);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns a pointer to the APE tag of the file.
|
||||
*
|
||||
* If \a create is false (the default) this may return a null pointer
|
||||
@@ -182,9 +185,9 @@ namespace TagLib {
|
||||
*
|
||||
* \see hasAPETag()
|
||||
*/
|
||||
APE::Tag *APETag(bool create = false);
|
||||
APE::Tag *APETag(bool create = false);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* This will remove the tags that match the OR-ed together TagTypes from the
|
||||
* file. By default it removes all tags.
|
||||
*
|
||||
@@ -193,48 +196,48 @@ namespace TagLib {
|
||||
*
|
||||
* \note In order to make the removal permanent save() still needs to be called.
|
||||
*/
|
||||
void strip(int tags = AllTags);
|
||||
void strip(int tags = AllTags);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \deprecated
|
||||
* \see strip
|
||||
*/
|
||||
TAGLIB_DEPRECATED void remove(int tags = AllTags);
|
||||
TAGLIB_DEPRECATED void remove(int tags = AllTags);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns whether or not the file on disk actually has an ID3v1 tag.
|
||||
*
|
||||
* \see ID3v1Tag()
|
||||
*/
|
||||
bool hasID3v1Tag() const;
|
||||
bool hasID3v1Tag() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns whether or not the file on disk actually has an APE tag.
|
||||
*
|
||||
* \see APETag()
|
||||
*/
|
||||
bool hasAPETag() const;
|
||||
bool hasAPETag() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns whether or not the given \a stream can be opened as an MPC
|
||||
* file.
|
||||
*
|
||||
* \note This method is designed to do a quick check. The result may
|
||||
* not necessarily be correct.
|
||||
*/
|
||||
static bool isSupported(IOStream *stream);
|
||||
static bool isSupported(IOStream *stream);
|
||||
|
||||
private:
|
||||
File(const File &);
|
||||
File &operator=(const File &);
|
||||
private:
|
||||
File(const File &);
|
||||
File &operator=(const File &);
|
||||
|
||||
void read(bool readProperties);
|
||||
void read(bool readProperties);
|
||||
|
||||
class FilePrivate;
|
||||
FilePrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
class FilePrivate;
|
||||
FilePrivate *d;
|
||||
};
|
||||
} // namespace MPC
|
||||
} // namespace TagLib
|
||||
} // namespace Strawberry_TagLib
|
||||
|
||||
#endif
|
||||
|
||||
213
3rdparty/taglib/mpc/mpcproperties.cpp
vendored
213
3rdparty/taglib/mpc/mpcproperties.cpp
vendored
@@ -33,21 +33,19 @@
|
||||
|
||||
using namespace Strawberry_TagLib::TagLib;
|
||||
|
||||
class MPC::Properties::PropertiesPrivate
|
||||
{
|
||||
public:
|
||||
PropertiesPrivate() :
|
||||
version(0),
|
||||
length(0),
|
||||
bitrate(0),
|
||||
sampleRate(0),
|
||||
channels(0),
|
||||
totalFrames(0),
|
||||
sampleFrames(0),
|
||||
trackGain(0),
|
||||
trackPeak(0),
|
||||
albumGain(0),
|
||||
albumPeak(0) {}
|
||||
class MPC::Properties::PropertiesPrivate {
|
||||
public:
|
||||
PropertiesPrivate() : version(0),
|
||||
length(0),
|
||||
bitrate(0),
|
||||
sampleRate(0),
|
||||
channels(0),
|
||||
totalFrames(0),
|
||||
sampleFrames(0),
|
||||
trackGain(0),
|
||||
trackPeak(0),
|
||||
albumGain(0),
|
||||
albumPeak(0) {}
|
||||
|
||||
int version;
|
||||
int length;
|
||||
@@ -66,19 +64,15 @@ public:
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
MPC::Properties::Properties(const ByteVector &data, long streamLength, ReadStyle style) :
|
||||
AudioProperties(style),
|
||||
d(new PropertiesPrivate())
|
||||
{
|
||||
MPC::Properties::Properties(const ByteVector &data, long streamLength, ReadStyle style) : AudioProperties(style),
|
||||
d(new PropertiesPrivate()) {
|
||||
readSV7(data, streamLength);
|
||||
}
|
||||
|
||||
MPC::Properties::Properties(File *file, long streamLength, ReadStyle style) :
|
||||
AudioProperties(style),
|
||||
d(new PropertiesPrivate())
|
||||
{
|
||||
MPC::Properties::Properties(File *file, long streamLength, ReadStyle style) : AudioProperties(style),
|
||||
d(new PropertiesPrivate()) {
|
||||
ByteVector magic = file->readBlock(4);
|
||||
if(magic == "MPCK") {
|
||||
if (magic == "MPCK") {
|
||||
// Musepack version 8
|
||||
readSV8(file, streamLength);
|
||||
}
|
||||
@@ -88,73 +82,59 @@ MPC::Properties::Properties(File *file, long streamLength, ReadStyle style) :
|
||||
}
|
||||
}
|
||||
|
||||
MPC::Properties::~Properties()
|
||||
{
|
||||
MPC::Properties::~Properties() {
|
||||
delete d;
|
||||
}
|
||||
|
||||
int MPC::Properties::length() const
|
||||
{
|
||||
int MPC::Properties::length() const {
|
||||
return lengthInSeconds();
|
||||
}
|
||||
|
||||
int MPC::Properties::lengthInSeconds() const
|
||||
{
|
||||
int MPC::Properties::lengthInSeconds() const {
|
||||
return d->length / 1000;
|
||||
}
|
||||
|
||||
int MPC::Properties::lengthInMilliseconds() const
|
||||
{
|
||||
int MPC::Properties::lengthInMilliseconds() const {
|
||||
return d->length;
|
||||
}
|
||||
|
||||
int MPC::Properties::bitrate() const
|
||||
{
|
||||
int MPC::Properties::bitrate() const {
|
||||
return d->bitrate;
|
||||
}
|
||||
|
||||
int MPC::Properties::sampleRate() const
|
||||
{
|
||||
int MPC::Properties::sampleRate() const {
|
||||
return d->sampleRate;
|
||||
}
|
||||
|
||||
int MPC::Properties::channels() const
|
||||
{
|
||||
int MPC::Properties::channels() const {
|
||||
return d->channels;
|
||||
}
|
||||
|
||||
int MPC::Properties::mpcVersion() const
|
||||
{
|
||||
int MPC::Properties::mpcVersion() const {
|
||||
return d->version;
|
||||
}
|
||||
|
||||
unsigned int MPC::Properties::totalFrames() const
|
||||
{
|
||||
unsigned int MPC::Properties::totalFrames() const {
|
||||
return d->totalFrames;
|
||||
}
|
||||
|
||||
unsigned int MPC::Properties::sampleFrames() const
|
||||
{
|
||||
unsigned int MPC::Properties::sampleFrames() const {
|
||||
return d->sampleFrames;
|
||||
}
|
||||
|
||||
int MPC::Properties::trackGain() const
|
||||
{
|
||||
int MPC::Properties::trackGain() const {
|
||||
return d->trackGain;
|
||||
}
|
||||
|
||||
int MPC::Properties::trackPeak() const
|
||||
{
|
||||
int MPC::Properties::trackPeak() const {
|
||||
return d->trackPeak;
|
||||
}
|
||||
|
||||
int MPC::Properties::albumGain() const
|
||||
{
|
||||
int MPC::Properties::albumGain() const {
|
||||
return d->albumGain;
|
||||
}
|
||||
|
||||
int MPC::Properties::albumPeak() const
|
||||
{
|
||||
int MPC::Properties::albumPeak() const {
|
||||
return d->albumPeak;
|
||||
}
|
||||
|
||||
@@ -162,58 +142,54 @@ int MPC::Properties::albumPeak() const
|
||||
// private members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace
|
||||
{
|
||||
unsigned long readSize(File *file, unsigned int &sizeLength, bool &eof)
|
||||
{
|
||||
sizeLength = 0;
|
||||
eof = false;
|
||||
namespace {
|
||||
unsigned long readSize(File *file, unsigned int &sizeLength, bool &eof) {
|
||||
sizeLength = 0;
|
||||
eof = false;
|
||||
|
||||
unsigned char tmp;
|
||||
unsigned long size = 0;
|
||||
unsigned char tmp;
|
||||
unsigned long size = 0;
|
||||
|
||||
do {
|
||||
const ByteVector b = file->readBlock(1);
|
||||
if(b.isEmpty()) {
|
||||
eof = true;
|
||||
break;
|
||||
}
|
||||
do {
|
||||
const ByteVector b = file->readBlock(1);
|
||||
if (b.isEmpty()) {
|
||||
eof = true;
|
||||
break;
|
||||
}
|
||||
|
||||
tmp = b[0];
|
||||
size = (size << 7) | (tmp & 0x7F);
|
||||
sizeLength++;
|
||||
} while((tmp & 0x80));
|
||||
return size;
|
||||
}
|
||||
|
||||
unsigned long readSize(const ByteVector &data, unsigned int &pos)
|
||||
{
|
||||
unsigned char tmp;
|
||||
unsigned long size = 0;
|
||||
|
||||
do {
|
||||
tmp = data[pos++];
|
||||
size = (size << 7) | (tmp & 0x7F);
|
||||
} while((tmp & 0x80) && (pos < data.size()));
|
||||
return size;
|
||||
}
|
||||
|
||||
// This array looks weird, but the same as original MusePack code found at:
|
||||
// https://www.musepack.net/index.php?pg=src
|
||||
const unsigned short sftable [8] = { 44100, 48000, 37800, 32000, 0, 0, 0, 0 };
|
||||
tmp = b[0];
|
||||
size = (size << 7) | (tmp & 0x7F);
|
||||
sizeLength++;
|
||||
} while ((tmp & 0x80));
|
||||
return size;
|
||||
}
|
||||
|
||||
void MPC::Properties::readSV8(File *file, long streamLength)
|
||||
{
|
||||
unsigned long readSize(const ByteVector &data, unsigned int &pos) {
|
||||
unsigned char tmp;
|
||||
unsigned long size = 0;
|
||||
|
||||
do {
|
||||
tmp = data[pos++];
|
||||
size = (size << 7) | (tmp & 0x7F);
|
||||
} while ((tmp & 0x80) && (pos < data.size()));
|
||||
return size;
|
||||
}
|
||||
|
||||
// This array looks weird, but the same as original MusePack code found at:
|
||||
// https://www.musepack.net/index.php?pg=src
|
||||
const unsigned short sftable[8] = { 44100, 48000, 37800, 32000, 0, 0, 0, 0 };
|
||||
} // namespace
|
||||
|
||||
void MPC::Properties::readSV8(File *file, long streamLength) {
|
||||
bool readSH = false, readRG = false;
|
||||
|
||||
while(!readSH && !readRG) {
|
||||
while (!readSH && !readRG) {
|
||||
const ByteVector packetType = file->readBlock(2);
|
||||
|
||||
unsigned int packetSizeLength;
|
||||
bool eof;
|
||||
const unsigned long packetSize = readSize(file, packetSizeLength, eof);
|
||||
if(eof) {
|
||||
if (eof) {
|
||||
debug("MPC::Properties::readSV8() - Reached to EOF.");
|
||||
break;
|
||||
}
|
||||
@@ -221,16 +197,16 @@ void MPC::Properties::readSV8(File *file, long streamLength)
|
||||
const unsigned long dataSize = packetSize - 2 - packetSizeLength;
|
||||
|
||||
const ByteVector data = file->readBlock(dataSize);
|
||||
if(data.size() != dataSize) {
|
||||
if (data.size() != dataSize) {
|
||||
debug("MPC::Properties::readSV8() - dataSize doesn't match the actual data size.");
|
||||
break;
|
||||
}
|
||||
|
||||
if(packetType == "SH") {
|
||||
if (packetType == "SH") {
|
||||
// Stream Header
|
||||
// http://trac.musepack.net/wiki/SV8Specification#StreamHeaderPacket
|
||||
|
||||
if(dataSize <= 5) {
|
||||
if (dataSize <= 5) {
|
||||
debug("MPC::Properties::readSV8() - \"SH\" packet is too short to parse.");
|
||||
break;
|
||||
}
|
||||
@@ -241,13 +217,13 @@ void MPC::Properties::readSV8(File *file, long streamLength)
|
||||
d->version = data[pos];
|
||||
pos += 1;
|
||||
d->sampleFrames = readSize(data, pos);
|
||||
if(pos > dataSize - 3) {
|
||||
if (pos > dataSize - 3) {
|
||||
debug("MPC::Properties::readSV8() - \"SH\" packet is corrupt.");
|
||||
break;
|
||||
}
|
||||
|
||||
const unsigned long begSilence = readSize(data, pos);
|
||||
if(pos > dataSize - 2) {
|
||||
if (pos > dataSize - 2) {
|
||||
debug("MPC::Properties::readSV8() - \"SH\" packet is corrupt.");
|
||||
break;
|
||||
}
|
||||
@@ -256,12 +232,12 @@ void MPC::Properties::readSV8(File *file, long streamLength)
|
||||
pos += 2;
|
||||
|
||||
d->sampleRate = sftable[(flags >> 13) & 0x07];
|
||||
d->channels = ((flags >> 4) & 0x0F) + 1;
|
||||
d->channels = ((flags >> 4) & 0x0F) + 1;
|
||||
|
||||
const unsigned int frameCount = d->sampleFrames - begSilence;
|
||||
if(frameCount > 0 && d->sampleRate > 0) {
|
||||
if (frameCount > 0 && d->sampleRate > 0) {
|
||||
const double length = frameCount * 1000.0 / d->sampleRate;
|
||||
d->length = static_cast<int>(length + 0.5);
|
||||
d->length = static_cast<int>(length + 0.5);
|
||||
d->bitrate = static_cast<int>(streamLength * 8.0 / length + 0.5);
|
||||
}
|
||||
}
|
||||
@@ -269,7 +245,7 @@ void MPC::Properties::readSV8(File *file, long streamLength)
|
||||
// Replay Gain
|
||||
// http://trac.musepack.net/wiki/SV8Specification#ReplaygainPacket
|
||||
|
||||
if(dataSize <= 9) {
|
||||
if (dataSize <= 9) {
|
||||
debug("MPC::Properties::readSV8() - \"RG\" packet is too short to parse.");
|
||||
break;
|
||||
}
|
||||
@@ -277,7 +253,7 @@ void MPC::Properties::readSV8(File *file, long streamLength)
|
||||
readRG = true;
|
||||
|
||||
const int replayGainVersion = data[0];
|
||||
if(replayGainVersion == 1) {
|
||||
if (replayGainVersion == 1) {
|
||||
d->trackGain = data.toShort(1, true);
|
||||
d->trackPeak = data.toShort(3, true);
|
||||
d->albumGain = data.toShort(5, true);
|
||||
@@ -285,7 +261,7 @@ void MPC::Properties::readSV8(File *file, long streamLength)
|
||||
}
|
||||
}
|
||||
|
||||
else if(packetType == "SE") {
|
||||
else if (packetType == "SE") {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -295,18 +271,17 @@ void MPC::Properties::readSV8(File *file, long streamLength)
|
||||
}
|
||||
}
|
||||
|
||||
void MPC::Properties::readSV7(const ByteVector &data, long streamLength)
|
||||
{
|
||||
if(data.startsWith("MP+")) {
|
||||
void MPC::Properties::readSV7(const ByteVector &data, long streamLength) {
|
||||
if (data.startsWith("MP+")) {
|
||||
d->version = data[3] & 15;
|
||||
if(d->version < 7)
|
||||
if (d->version < 7)
|
||||
return;
|
||||
|
||||
d->totalFrames = data.toUInt(4, false);
|
||||
|
||||
const unsigned int flags = data.toUInt(8, false);
|
||||
d->sampleRate = sftable[(flags >> 16) & 0x03];
|
||||
d->channels = 2;
|
||||
d->channels = 2;
|
||||
|
||||
const unsigned int gapless = data.toUInt(5, false);
|
||||
|
||||
@@ -316,15 +291,15 @@ void MPC::Properties::readSV7(const ByteVector &data, long streamLength)
|
||||
d->albumPeak = data.toUShort(16, false);
|
||||
|
||||
// convert gain info
|
||||
if(d->trackGain != 0) {
|
||||
if (d->trackGain != 0) {
|
||||
int tmp = (int)((64.82 - (short)d->trackGain / 100.) * 256. + .5);
|
||||
if(tmp >= (1 << 16) || tmp < 0) tmp = 0;
|
||||
if (tmp >= (1 << 16) || tmp < 0) tmp = 0;
|
||||
d->trackGain = tmp;
|
||||
}
|
||||
|
||||
if(d->albumGain != 0) {
|
||||
if (d->albumGain != 0) {
|
||||
int tmp = (int)((64.82 - d->albumGain / 100.) * 256. + .5);
|
||||
if(tmp >= (1 << 16) || tmp < 0) tmp = 0;
|
||||
if (tmp >= (1 << 16) || tmp < 0) tmp = 0;
|
||||
d->albumGain = tmp;
|
||||
}
|
||||
|
||||
@@ -335,7 +310,7 @@ void MPC::Properties::readSV7(const ByteVector &data, long streamLength)
|
||||
d->albumPeak = (int)(log10((double)d->albumPeak) * 20 * 256 + .5);
|
||||
|
||||
bool trueGapless = (gapless >> 31) & 0x0001;
|
||||
if(trueGapless) {
|
||||
if (trueGapless) {
|
||||
unsigned int lastFrameSamples = (gapless >> 20) & 0x07FF;
|
||||
d->sampleFrames = d->totalFrames * 1152 - lastFrameSamples;
|
||||
}
|
||||
@@ -345,12 +320,12 @@ void MPC::Properties::readSV7(const ByteVector &data, long streamLength)
|
||||
else {
|
||||
const unsigned int headerData = data.toUInt(0, false);
|
||||
|
||||
d->bitrate = (headerData >> 23) & 0x01ff;
|
||||
d->version = (headerData >> 11) & 0x03ff;
|
||||
d->bitrate = (headerData >> 23) & 0x01ff;
|
||||
d->version = (headerData >> 11) & 0x03ff;
|
||||
d->sampleRate = 44100;
|
||||
d->channels = 2;
|
||||
d->channels = 2;
|
||||
|
||||
if(d->version >= 5)
|
||||
if (d->version >= 5)
|
||||
d->totalFrames = data.toUInt(4, false);
|
||||
else
|
||||
d->totalFrames = data.toUShort(6, false);
|
||||
@@ -358,11 +333,11 @@ void MPC::Properties::readSV7(const ByteVector &data, long streamLength)
|
||||
d->sampleFrames = d->totalFrames * 1152 - 576;
|
||||
}
|
||||
|
||||
if(d->sampleFrames > 0 && d->sampleRate > 0) {
|
||||
if (d->sampleFrames > 0 && d->sampleRate > 0) {
|
||||
const double length = d->sampleFrames * 1000.0 / d->sampleRate;
|
||||
d->length = static_cast<int>(length + 0.5);
|
||||
|
||||
if(d->bitrate == 0)
|
||||
if (d->bitrate == 0)
|
||||
d->bitrate = static_cast<int>(streamLength * 8.0 / length + 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
101
3rdparty/taglib/mpc/mpcproperties.h
vendored
101
3rdparty/taglib/mpc/mpcproperties.h
vendored
@@ -32,42 +32,41 @@
|
||||
namespace Strawberry_TagLib {
|
||||
namespace TagLib {
|
||||
|
||||
namespace MPC {
|
||||
namespace MPC {
|
||||
|
||||
class File;
|
||||
class File;
|
||||
|
||||
static const unsigned int HeaderSize = 8 * 7;
|
||||
static const unsigned int HeaderSize = 8 * 7;
|
||||
|
||||
//! An implementation of audio property reading for MPC
|
||||
//! An implementation of audio property reading for MPC
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* This reads the data from an MPC stream found in the AudioProperties
|
||||
* API.
|
||||
*/
|
||||
|
||||
class TAGLIB_EXPORT Properties : public AudioProperties
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
class TAGLIB_EXPORT Properties : public AudioProperties {
|
||||
public:
|
||||
/*!
|
||||
* Create an instance of MPC::Properties with the data read from the
|
||||
* ByteVector \a data.
|
||||
*
|
||||
* This constructor is deprecated. It only works for MPC version up to 7.
|
||||
*/
|
||||
Properties(const ByteVector &data, long streamLength, ReadStyle style = Average);
|
||||
Properties(const ByteVector &data, long streamLength, ReadStyle style = Average);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Create an instance of MPC::Properties with the data read directly
|
||||
* from a MPC::File.
|
||||
*/
|
||||
Properties(File *file, long streamLength, ReadStyle style = Average);
|
||||
Properties(File *file, long streamLength, ReadStyle style = Average);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Destroys this MPC::Properties instance.
|
||||
*/
|
||||
virtual ~Properties();
|
||||
virtual ~Properties();
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns the length of the file in seconds. The length is rounded down to
|
||||
* the nearest whole second.
|
||||
*
|
||||
@@ -75,86 +74,86 @@ namespace TagLib {
|
||||
*
|
||||
* \deprecated
|
||||
*/
|
||||
TAGLIB_DEPRECATED virtual int length() const;
|
||||
TAGLIB_DEPRECATED virtual int length() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns the length of the file in seconds. The length is rounded down to
|
||||
* the nearest whole second.
|
||||
*
|
||||
* \see lengthInMilliseconds()
|
||||
*/
|
||||
// BIC: make virtual
|
||||
int lengthInSeconds() const;
|
||||
// BIC: make virtual
|
||||
int lengthInSeconds() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns the length of the file in milliseconds.
|
||||
*
|
||||
* \see lengthInSeconds()
|
||||
*/
|
||||
// BIC: make virtual
|
||||
int lengthInMilliseconds() const;
|
||||
// BIC: make virtual
|
||||
int lengthInMilliseconds() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns the average bit rate of the file in kb/s.
|
||||
*/
|
||||
virtual int bitrate() const;
|
||||
virtual int bitrate() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns the sample rate in Hz.
|
||||
*/
|
||||
virtual int sampleRate() const;
|
||||
virtual int sampleRate() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns the number of audio channels.
|
||||
*/
|
||||
virtual int channels() const;
|
||||
virtual int channels() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns the version of the bitstream (SV4-SV8)
|
||||
*/
|
||||
int mpcVersion() const;
|
||||
int mpcVersion() const;
|
||||
|
||||
unsigned int totalFrames() const;
|
||||
unsigned int sampleFrames() const;
|
||||
unsigned int totalFrames() const;
|
||||
unsigned int sampleFrames() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns the track gain as an integer value,
|
||||
* to convert to dB: trackGain in dB = 64.82 - (trackGain / 256)
|
||||
*/
|
||||
int trackGain() const;
|
||||
int trackGain() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns the track peak as an integer value,
|
||||
* to convert to dB: trackPeak in dB = trackPeak / 256
|
||||
* to convert to floating [-1..1]: trackPeak = 10^(trackPeak / 256 / 20)/32768
|
||||
*/
|
||||
int trackPeak() const;
|
||||
int trackPeak() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns the album gain as an integer value,
|
||||
* to convert to dB: albumGain in dB = 64.82 - (albumGain / 256)
|
||||
*/
|
||||
int albumGain() const;
|
||||
int albumGain() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns the album peak as an integer value,
|
||||
* to convert to dB: albumPeak in dB = albumPeak / 256
|
||||
* to convert to floating [-1..1]: albumPeak = 10^(albumPeak / 256 / 20)/32768
|
||||
*/
|
||||
int albumPeak() const;
|
||||
int albumPeak() const;
|
||||
|
||||
private:
|
||||
Properties(const Properties &);
|
||||
Properties &operator=(const Properties &);
|
||||
private:
|
||||
Properties(const Properties &);
|
||||
Properties &operator=(const Properties &);
|
||||
|
||||
void readSV7(const ByteVector &data, long streamLength);
|
||||
void readSV8(File *file, long streamLength);
|
||||
void readSV7(const ByteVector &data, long streamLength);
|
||||
void readSV8(File *file, long streamLength);
|
||||
|
||||
class PropertiesPrivate;
|
||||
PropertiesPrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
class PropertiesPrivate;
|
||||
PropertiesPrivate *d;
|
||||
};
|
||||
} // namespace MPC
|
||||
} // namespace TagLib
|
||||
} // namespace Strawberry_TagLib
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user