Format taglib sources
This commit is contained in:
84
3rdparty/taglib/riff/aiff/aifffile.cpp
vendored
84
3rdparty/taglib/riff/aiff/aifffile.cpp
vendored
@@ -34,16 +34,13 @@
|
||||
|
||||
using namespace Strawberry_TagLib::TagLib;
|
||||
|
||||
class RIFF::AIFF::File::FilePrivate
|
||||
{
|
||||
public:
|
||||
FilePrivate() :
|
||||
properties(0),
|
||||
tag(0),
|
||||
hasID3v2(false) {}
|
||||
class RIFF::AIFF::File::FilePrivate {
|
||||
public:
|
||||
FilePrivate() : properties(0),
|
||||
tag(0),
|
||||
hasID3v2(false) {}
|
||||
|
||||
~FilePrivate()
|
||||
{
|
||||
~FilePrivate() {
|
||||
delete properties;
|
||||
delete tag;
|
||||
}
|
||||
@@ -58,8 +55,7 @@ public:
|
||||
// static members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool RIFF::AIFF::File::isSupported(IOStream *stream)
|
||||
{
|
||||
bool RIFF::AIFF::File::isSupported(IOStream *stream) {
|
||||
// An AIFF file has to start with "FORM????AIFF" or "FORM????AIFC".
|
||||
|
||||
const ByteVector id = Utils::readHeader(stream, 12, false);
|
||||
@@ -70,76 +66,64 @@ bool RIFF::AIFF::File::isSupported(IOStream *stream)
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
RIFF::AIFF::File::File(FileName file, bool readProperties, Properties::ReadStyle) :
|
||||
RIFF::File(file, BigEndian),
|
||||
d(new FilePrivate())
|
||||
{
|
||||
if(isOpen())
|
||||
RIFF::AIFF::File::File(FileName file, bool readProperties, Properties::ReadStyle) : RIFF::File(file, BigEndian),
|
||||
d(new FilePrivate()) {
|
||||
if (isOpen())
|
||||
read(readProperties);
|
||||
}
|
||||
|
||||
RIFF::AIFF::File::File(IOStream *stream, bool readProperties, Properties::ReadStyle) :
|
||||
RIFF::File(stream, BigEndian),
|
||||
d(new FilePrivate())
|
||||
{
|
||||
if(isOpen())
|
||||
RIFF::AIFF::File::File(IOStream *stream, bool readProperties, Properties::ReadStyle) : RIFF::File(stream, BigEndian),
|
||||
d(new FilePrivate()) {
|
||||
if (isOpen())
|
||||
read(readProperties);
|
||||
}
|
||||
|
||||
RIFF::AIFF::File::~File()
|
||||
{
|
||||
RIFF::AIFF::File::~File() {
|
||||
delete d;
|
||||
}
|
||||
|
||||
ID3v2::Tag *RIFF::AIFF::File::tag() const
|
||||
{
|
||||
ID3v2::Tag *RIFF::AIFF::File::tag() const {
|
||||
return d->tag;
|
||||
}
|
||||
|
||||
PropertyMap RIFF::AIFF::File::properties() const
|
||||
{
|
||||
PropertyMap RIFF::AIFF::File::properties() const {
|
||||
return d->tag->properties();
|
||||
}
|
||||
|
||||
void RIFF::AIFF::File::removeUnsupportedProperties(const StringList &unsupported)
|
||||
{
|
||||
void RIFF::AIFF::File::removeUnsupportedProperties(const StringList &unsupported) {
|
||||
d->tag->removeUnsupportedProperties(unsupported);
|
||||
}
|
||||
|
||||
PropertyMap RIFF::AIFF::File::setProperties(const PropertyMap &properties)
|
||||
{
|
||||
PropertyMap RIFF::AIFF::File::setProperties(const PropertyMap &properties) {
|
||||
return d->tag->setProperties(properties);
|
||||
}
|
||||
|
||||
RIFF::AIFF::Properties *RIFF::AIFF::File::audioProperties() const
|
||||
{
|
||||
RIFF::AIFF::Properties *RIFF::AIFF::File::audioProperties() const {
|
||||
return d->properties;
|
||||
}
|
||||
|
||||
bool RIFF::AIFF::File::save()
|
||||
{
|
||||
return save(ID3v2::v4);
|
||||
bool RIFF::AIFF::File::save() {
|
||||
return save(ID3v2::v4);
|
||||
}
|
||||
|
||||
bool RIFF::AIFF::File::save(ID3v2::Version version)
|
||||
{
|
||||
if(readOnly()) {
|
||||
bool RIFF::AIFF::File::save(ID3v2::Version version) {
|
||||
if (readOnly()) {
|
||||
debug("RIFF::AIFF::File::save() -- File is read only.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!isValid()) {
|
||||
if (!isValid()) {
|
||||
debug("RIFF::AIFF::File::save() -- Trying to save invalid file.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(d->hasID3v2) {
|
||||
if (d->hasID3v2) {
|
||||
removeChunk("ID3 ");
|
||||
removeChunk("id3 ");
|
||||
d->hasID3v2 = false;
|
||||
}
|
||||
|
||||
if(tag() && !tag()->isEmpty()) {
|
||||
if (tag() && !tag()->isEmpty()) {
|
||||
setChunkData("ID3 ", d->tag->render(version));
|
||||
d->hasID3v2 = true;
|
||||
}
|
||||
@@ -147,8 +131,7 @@ bool RIFF::AIFF::File::save(ID3v2::Version version)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RIFF::AIFF::File::hasID3v2Tag() const
|
||||
{
|
||||
bool RIFF::AIFF::File::hasID3v2Tag() const {
|
||||
return d->hasID3v2;
|
||||
}
|
||||
|
||||
@@ -156,12 +139,11 @@ bool RIFF::AIFF::File::hasID3v2Tag() const
|
||||
// private members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void RIFF::AIFF::File::read(bool readProperties)
|
||||
{
|
||||
for(unsigned int i = 0; i < chunkCount(); ++i) {
|
||||
void RIFF::AIFF::File::read(bool readProperties) {
|
||||
for (unsigned int i = 0; i < chunkCount(); ++i) {
|
||||
const ByteVector name = chunkName(i);
|
||||
if(name == "ID3 " || name == "id3 ") {
|
||||
if(!d->tag) {
|
||||
if (name == "ID3 " || name == "id3 ") {
|
||||
if (!d->tag) {
|
||||
d->tag = new ID3v2::Tag(this, chunkOffset(i));
|
||||
d->hasID3v2 = true;
|
||||
}
|
||||
@@ -171,9 +153,9 @@ void RIFF::AIFF::File::read(bool readProperties)
|
||||
}
|
||||
}
|
||||
|
||||
if(!d->tag)
|
||||
if (!d->tag)
|
||||
d->tag = new ID3v2::Tag();
|
||||
|
||||
if(readProperties)
|
||||
if (readProperties)
|
||||
d->properties = new Properties(this, Properties::Average);
|
||||
}
|
||||
|
||||
91
3rdparty/taglib/riff/aiff/aifffile.h
vendored
91
3rdparty/taglib/riff/aiff/aifffile.h
vendored
@@ -33,41 +33,40 @@
|
||||
namespace Strawberry_TagLib {
|
||||
namespace TagLib {
|
||||
|
||||
namespace RIFF {
|
||||
namespace RIFF {
|
||||
|
||||
//! An implementation of AIFF metadata
|
||||
//! An implementation of AIFF metadata
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* This is implementation of AIFF metadata.
|
||||
*
|
||||
* This supports an ID3v2 tag as well as reading stream from the ID3 RIFF
|
||||
* chunk as well as properties from the file.
|
||||
*/
|
||||
|
||||
namespace AIFF {
|
||||
namespace AIFF {
|
||||
|
||||
//! An implementation of TagLib::File with AIFF specific methods
|
||||
//! An implementation of TagLib::File with AIFF specific methods
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* This implements and provides an interface for AIFF files to the
|
||||
* TagLib::Tag and TagLib::AudioProperties interfaces by way of implementing
|
||||
* the abstract TagLib::File API as well as providing some additional
|
||||
* information specific to AIFF files.
|
||||
*/
|
||||
|
||||
class TAGLIB_EXPORT File : public Strawberry_TagLib::TagLib::RIFF::File
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
class TAGLIB_EXPORT File : public Strawberry_TagLib::TagLib::RIFF::File {
|
||||
public:
|
||||
/*!
|
||||
* Constructs an AIFF 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 AIFF file from \a stream. If \a readProperties is true the
|
||||
* file's audio properties will also be read.
|
||||
*
|
||||
@@ -76,15 +75,15 @@ 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.
|
||||
*
|
||||
* \note This always returns a valid pointer regardless of whether or not
|
||||
@@ -93,67 +92,67 @@ namespace TagLib {
|
||||
*
|
||||
* \see hasID3v2Tag()
|
||||
*/
|
||||
virtual ID3v2::Tag *tag() const;
|
||||
virtual ID3v2::Tag *tag() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Implements the unified property interface -- export function.
|
||||
* This method forwards to ID3v2::Tag::properties().
|
||||
*/
|
||||
PropertyMap properties() const;
|
||||
PropertyMap properties() const;
|
||||
|
||||
void removeUnsupportedProperties(const StringList &properties);
|
||||
void removeUnsupportedProperties(const StringList &properties);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Implements the unified property interface -- import function.
|
||||
* This method forwards to ID3v2::Tag::setProperties().
|
||||
*/
|
||||
PropertyMap setProperties(const PropertyMap &);
|
||||
PropertyMap setProperties(const PropertyMap &);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns the AIFF::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.
|
||||
*/
|
||||
virtual bool save();
|
||||
virtual bool save();
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Save using a specific ID3v2 version (e.g. v3)
|
||||
*/
|
||||
bool save(ID3v2::Version version);
|
||||
bool save(ID3v2::Version version);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns whether or not the file on disk actually has an ID3v2 tag.
|
||||
*
|
||||
* \see ID3v2Tag()
|
||||
*/
|
||||
bool hasID3v2Tag() const;
|
||||
bool hasID3v2Tag() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Check if the given \a stream can be opened as an AIFF 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);
|
||||
|
||||
friend class Properties;
|
||||
friend class Properties;
|
||||
|
||||
class FilePrivate;
|
||||
FilePrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
class FilePrivate;
|
||||
FilePrivate *d;
|
||||
};
|
||||
} // namespace AIFF
|
||||
} // namespace RIFF
|
||||
} // namespace TagLib
|
||||
} // namespace Strawberry_TagLib
|
||||
|
||||
#endif
|
||||
|
||||
101
3rdparty/taglib/riff/aiff/aiffproperties.cpp
vendored
101
3rdparty/taglib/riff/aiff/aiffproperties.cpp
vendored
@@ -30,16 +30,14 @@
|
||||
|
||||
using namespace Strawberry_TagLib::TagLib;
|
||||
|
||||
class RIFF::AIFF::Properties::PropertiesPrivate
|
||||
{
|
||||
public:
|
||||
PropertiesPrivate() :
|
||||
length(0),
|
||||
bitrate(0),
|
||||
sampleRate(0),
|
||||
channels(0),
|
||||
bitsPerSample(0),
|
||||
sampleFrames(0) {}
|
||||
class RIFF::AIFF::Properties::PropertiesPrivate {
|
||||
public:
|
||||
PropertiesPrivate() : length(0),
|
||||
bitrate(0),
|
||||
sampleRate(0),
|
||||
channels(0),
|
||||
bitsPerSample(0),
|
||||
sampleFrames(0) {}
|
||||
|
||||
int length;
|
||||
int bitrate;
|
||||
@@ -57,82 +55,65 @@ public:
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
RIFF::AIFF::Properties::Properties(const ByteVector &, ReadStyle style) :
|
||||
AudioProperties(style),
|
||||
d(new PropertiesPrivate())
|
||||
{
|
||||
RIFF::AIFF::Properties::Properties(const ByteVector &, ReadStyle style) : AudioProperties(style),
|
||||
d(new PropertiesPrivate()) {
|
||||
debug("RIFF::AIFF::Properties::Properties() - This constructor is no longer used.");
|
||||
}
|
||||
|
||||
RIFF::AIFF::Properties::Properties(File *file, ReadStyle style) :
|
||||
AudioProperties(style),
|
||||
d(new PropertiesPrivate())
|
||||
{
|
||||
RIFF::AIFF::Properties::Properties(File *file, ReadStyle style) : AudioProperties(style),
|
||||
d(new PropertiesPrivate()) {
|
||||
read(file);
|
||||
}
|
||||
|
||||
RIFF::AIFF::Properties::~Properties()
|
||||
{
|
||||
RIFF::AIFF::Properties::~Properties() {
|
||||
delete d;
|
||||
}
|
||||
|
||||
int RIFF::AIFF::Properties::length() const
|
||||
{
|
||||
int RIFF::AIFF::Properties::length() const {
|
||||
return lengthInSeconds();
|
||||
}
|
||||
|
||||
int RIFF::AIFF::Properties::lengthInSeconds() const
|
||||
{
|
||||
int RIFF::AIFF::Properties::lengthInSeconds() const {
|
||||
return d->length / 1000;
|
||||
}
|
||||
|
||||
int RIFF::AIFF::Properties::lengthInMilliseconds() const
|
||||
{
|
||||
int RIFF::AIFF::Properties::lengthInMilliseconds() const {
|
||||
return d->length;
|
||||
}
|
||||
|
||||
int RIFF::AIFF::Properties::bitrate() const
|
||||
{
|
||||
int RIFF::AIFF::Properties::bitrate() const {
|
||||
return d->bitrate;
|
||||
}
|
||||
|
||||
int RIFF::AIFF::Properties::sampleRate() const
|
||||
{
|
||||
int RIFF::AIFF::Properties::sampleRate() const {
|
||||
return d->sampleRate;
|
||||
}
|
||||
|
||||
int RIFF::AIFF::Properties::channels() const
|
||||
{
|
||||
int RIFF::AIFF::Properties::channels() const {
|
||||
return d->channels;
|
||||
}
|
||||
|
||||
int RIFF::AIFF::Properties::bitsPerSample() const
|
||||
{
|
||||
int RIFF::AIFF::Properties::bitsPerSample() const {
|
||||
return d->bitsPerSample;
|
||||
}
|
||||
|
||||
int RIFF::AIFF::Properties::sampleWidth() const
|
||||
{
|
||||
int RIFF::AIFF::Properties::sampleWidth() const {
|
||||
return bitsPerSample();
|
||||
}
|
||||
|
||||
unsigned int RIFF::AIFF::Properties::sampleFrames() const
|
||||
{
|
||||
unsigned int RIFF::AIFF::Properties::sampleFrames() const {
|
||||
return d->sampleFrames;
|
||||
}
|
||||
|
||||
bool RIFF::AIFF::Properties::isAiffC() const
|
||||
{
|
||||
bool RIFF::AIFF::Properties::isAiffC() const {
|
||||
return (!d->compressionType.isEmpty());
|
||||
}
|
||||
|
||||
ByteVector RIFF::AIFF::Properties::compressionType() const
|
||||
{
|
||||
ByteVector RIFF::AIFF::Properties::compressionType() const {
|
||||
return d->compressionType;
|
||||
}
|
||||
|
||||
String RIFF::AIFF::Properties::compressionName() const
|
||||
{
|
||||
String RIFF::AIFF::Properties::compressionName() const {
|
||||
return d->compressionName;
|
||||
}
|
||||
|
||||
@@ -140,53 +121,51 @@ String RIFF::AIFF::Properties::compressionName() const
|
||||
// private members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void RIFF::AIFF::Properties::read(File *file)
|
||||
{
|
||||
void RIFF::AIFF::Properties::read(File *file) {
|
||||
ByteVector data;
|
||||
unsigned int streamLength = 0;
|
||||
for(unsigned int i = 0; i < file->chunkCount(); i++) {
|
||||
for (unsigned int i = 0; i < file->chunkCount(); i++) {
|
||||
const ByteVector name = file->chunkName(i);
|
||||
if(name == "COMM") {
|
||||
if(data.isEmpty())
|
||||
if (name == "COMM") {
|
||||
if (data.isEmpty())
|
||||
data = file->chunkData(i);
|
||||
else
|
||||
debug("RIFF::AIFF::Properties::read() - Duplicate 'COMM' chunk found.");
|
||||
}
|
||||
else if(name == "SSND") {
|
||||
if(streamLength == 0)
|
||||
else if (name == "SSND") {
|
||||
if (streamLength == 0)
|
||||
streamLength = file->chunkDataSize(i) + file->chunkPadding(i);
|
||||
else
|
||||
debug("RIFF::AIFF::Properties::read() - Duplicate 'SSND' chunk found.");
|
||||
}
|
||||
}
|
||||
|
||||
if(data.size() < 18) {
|
||||
if (data.size() < 18) {
|
||||
debug("RIFF::AIFF::Properties::read() - 'COMM' chunk not found or too short.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(streamLength == 0) {
|
||||
if (streamLength == 0) {
|
||||
debug("RIFF::AIFF::Properties::read() - 'SSND' chunk not found.");
|
||||
return;
|
||||
}
|
||||
|
||||
d->channels = data.toShort(0U);
|
||||
d->sampleFrames = data.toUInt(2U);
|
||||
d->channels = data.toShort(0U);
|
||||
d->sampleFrames = data.toUInt(2U);
|
||||
d->bitsPerSample = data.toShort(6U);
|
||||
|
||||
const long double sampleRate = data.toFloat80BE(8);
|
||||
if(sampleRate >= 1.0)
|
||||
if (sampleRate >= 1.0)
|
||||
d->sampleRate = static_cast<int>(sampleRate + 0.5);
|
||||
|
||||
if(d->sampleFrames > 0 && d->sampleRate > 0) {
|
||||
if (d->sampleFrames > 0 && d->sampleRate > 0) {
|
||||
const double length = d->sampleFrames * 1000.0 / 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);
|
||||
}
|
||||
|
||||
if(data.size() >= 23) {
|
||||
if (data.size() >= 23) {
|
||||
d->compressionType = data.mid(18, 4);
|
||||
d->compressionName
|
||||
= String(data.mid(23, static_cast<unsigned char>(data[22])), String::Latin1);
|
||||
d->compressionName = String(data.mid(23, static_cast<unsigned char>(data[22])), String::Latin1);
|
||||
}
|
||||
}
|
||||
|
||||
101
3rdparty/taglib/riff/aiff/aiffproperties.h
vendored
101
3rdparty/taglib/riff/aiff/aiffproperties.h
vendored
@@ -31,42 +31,41 @@
|
||||
namespace Strawberry_TagLib {
|
||||
namespace TagLib {
|
||||
|
||||
namespace RIFF {
|
||||
namespace RIFF {
|
||||
|
||||
namespace AIFF {
|
||||
namespace AIFF {
|
||||
|
||||
class File;
|
||||
class File;
|
||||
|
||||
//! An implementation of audio property reading for AIFF
|
||||
//! An implementation of audio property reading for AIFF
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* This reads the data from an AIFF stream found in the AudioProperties
|
||||
* API.
|
||||
*/
|
||||
|
||||
class TAGLIB_EXPORT Properties : public AudioProperties
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
class TAGLIB_EXPORT Properties : public AudioProperties {
|
||||
public:
|
||||
/*!
|
||||
* Create an instance of AIFF::Properties with the data read from the
|
||||
* ByteVector \a data.
|
||||
*
|
||||
* \deprecated
|
||||
*/
|
||||
TAGLIB_DEPRECATED Properties(const ByteVector &data, ReadStyle style);
|
||||
TAGLIB_DEPRECATED Properties(const ByteVector &data, ReadStyle style);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Create an instance of AIFF::Properties with the data read from the
|
||||
* AIFF::File \a file.
|
||||
*/
|
||||
Properties(File *file, ReadStyle style);
|
||||
Properties(File *file, ReadStyle style);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Destroys this AIFF::Properties instance.
|
||||
*/
|
||||
virtual ~Properties();
|
||||
virtual ~Properties();
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns the length of the file in seconds. The length is rounded down to
|
||||
* the nearest whole second.
|
||||
*
|
||||
@@ -74,65 +73,65 @@ 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 number of bits per audio sample.
|
||||
*/
|
||||
int bitsPerSample() const;
|
||||
int bitsPerSample() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns the number of bits per audio sample.
|
||||
*
|
||||
* \note This method is just an alias of bitsPerSample().
|
||||
*
|
||||
* \deprecated
|
||||
*/
|
||||
TAGLIB_DEPRECATED int sampleWidth() const;
|
||||
TAGLIB_DEPRECATED int sampleWidth() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns the number of sample frames
|
||||
*/
|
||||
unsigned int sampleFrames() const;
|
||||
unsigned int sampleFrames() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns true if the file is in AIFF-C format, false if AIFF format.
|
||||
*/
|
||||
bool isAiffC() const;
|
||||
bool isAiffC() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns the compression type of the AIFF-C file. For example, "NONE" for
|
||||
* not compressed, "ACE2" for ACE 2-to-1.
|
||||
*
|
||||
@@ -140,29 +139,29 @@ namespace TagLib {
|
||||
*
|
||||
* \see isAiffC()
|
||||
*/
|
||||
ByteVector compressionType() const;
|
||||
ByteVector compressionType() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns the concrete compression name of the AIFF-C file.
|
||||
*
|
||||
* If the file is in AIFF format, always returns an empty string.
|
||||
*
|
||||
* \see isAiffC()
|
||||
*/
|
||||
String compressionName() const;
|
||||
String compressionName() const;
|
||||
|
||||
private:
|
||||
Properties(const Properties &);
|
||||
Properties &operator=(const Properties &);
|
||||
private:
|
||||
Properties(const Properties &);
|
||||
Properties &operator=(const Properties &);
|
||||
|
||||
void read(File *file);
|
||||
void read(File *file);
|
||||
|
||||
class PropertiesPrivate;
|
||||
PropertiesPrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
class PropertiesPrivate;
|
||||
PropertiesPrivate *d;
|
||||
};
|
||||
} // namespace AIFF
|
||||
} // namespace RIFF
|
||||
} // namespace TagLib
|
||||
} // namespace Strawberry_TagLib
|
||||
|
||||
#endif
|
||||
|
||||
155
3rdparty/taglib/riff/rifffile.cpp
vendored
155
3rdparty/taglib/riff/rifffile.cpp
vendored
@@ -35,21 +35,18 @@
|
||||
|
||||
using namespace Strawberry_TagLib::TagLib;
|
||||
|
||||
struct Chunk
|
||||
{
|
||||
ByteVector name;
|
||||
struct Chunk {
|
||||
ByteVector name;
|
||||
unsigned int offset;
|
||||
unsigned int size;
|
||||
unsigned int padding;
|
||||
};
|
||||
|
||||
class RIFF::File::FilePrivate
|
||||
{
|
||||
public:
|
||||
explicit FilePrivate(Endianness _endianness) :
|
||||
endianness(_endianness),
|
||||
size(0),
|
||||
sizeOffset(0) {}
|
||||
class RIFF::File::FilePrivate {
|
||||
public:
|
||||
explicit FilePrivate(Endianness _endianness) : endianness(_endianness),
|
||||
size(0),
|
||||
sizeOffset(0) {}
|
||||
|
||||
const Endianness endianness;
|
||||
|
||||
@@ -63,8 +60,7 @@ public:
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
RIFF::File::~File()
|
||||
{
|
||||
RIFF::File::~File() {
|
||||
delete d;
|
||||
}
|
||||
|
||||
@@ -72,35 +68,28 @@ RIFF::File::~File()
|
||||
// protected members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
RIFF::File::File(FileName file, Endianness endianness) :
|
||||
Strawberry_TagLib::TagLib::File(file),
|
||||
d(new FilePrivate(endianness))
|
||||
{
|
||||
if(isOpen())
|
||||
RIFF::File::File(FileName file, Endianness endianness) : Strawberry_TagLib::TagLib::File(file),
|
||||
d(new FilePrivate(endianness)) {
|
||||
if (isOpen())
|
||||
read();
|
||||
}
|
||||
|
||||
RIFF::File::File(IOStream *stream, Endianness endianness) :
|
||||
Strawberry_TagLib::TagLib::File(stream),
|
||||
d(new FilePrivate(endianness))
|
||||
{
|
||||
if(isOpen())
|
||||
RIFF::File::File(IOStream *stream, Endianness endianness) : Strawberry_TagLib::TagLib::File(stream),
|
||||
d(new FilePrivate(endianness)) {
|
||||
if (isOpen())
|
||||
read();
|
||||
}
|
||||
|
||||
unsigned int RIFF::File::riffSize() const
|
||||
{
|
||||
unsigned int RIFF::File::riffSize() const {
|
||||
return d->size;
|
||||
}
|
||||
|
||||
unsigned int RIFF::File::chunkCount() const
|
||||
{
|
||||
unsigned int RIFF::File::chunkCount() const {
|
||||
return static_cast<unsigned int>(d->chunks.size());
|
||||
}
|
||||
|
||||
unsigned int RIFF::File::chunkDataSize(unsigned int i) const
|
||||
{
|
||||
if(i >= d->chunks.size()) {
|
||||
unsigned int RIFF::File::chunkDataSize(unsigned int i) const {
|
||||
if (i >= d->chunks.size()) {
|
||||
debug("RIFF::File::chunkDataSize() - Index out of range. Returning 0.");
|
||||
return 0;
|
||||
}
|
||||
@@ -108,9 +97,8 @@ unsigned int RIFF::File::chunkDataSize(unsigned int i) const
|
||||
return d->chunks[i].size;
|
||||
}
|
||||
|
||||
unsigned int RIFF::File::chunkOffset(unsigned int i) const
|
||||
{
|
||||
if(i >= d->chunks.size()) {
|
||||
unsigned int RIFF::File::chunkOffset(unsigned int i) const {
|
||||
if (i >= d->chunks.size()) {
|
||||
debug("RIFF::File::chunkOffset() - Index out of range. Returning 0.");
|
||||
return 0;
|
||||
}
|
||||
@@ -118,9 +106,8 @@ unsigned int RIFF::File::chunkOffset(unsigned int i) const
|
||||
return d->chunks[i].offset;
|
||||
}
|
||||
|
||||
unsigned int RIFF::File::chunkPadding(unsigned int i) const
|
||||
{
|
||||
if(i >= d->chunks.size()) {
|
||||
unsigned int RIFF::File::chunkPadding(unsigned int i) const {
|
||||
if (i >= d->chunks.size()) {
|
||||
debug("RIFF::File::chunkPadding() - Index out of range. Returning 0.");
|
||||
return 0;
|
||||
}
|
||||
@@ -128,9 +115,8 @@ unsigned int RIFF::File::chunkPadding(unsigned int i) const
|
||||
return d->chunks[i].padding;
|
||||
}
|
||||
|
||||
ByteVector RIFF::File::chunkName(unsigned int i) const
|
||||
{
|
||||
if(i >= d->chunks.size()) {
|
||||
ByteVector RIFF::File::chunkName(unsigned int i) const {
|
||||
if (i >= d->chunks.size()) {
|
||||
debug("RIFF::File::chunkName() - Index out of range. Returning an empty vector.");
|
||||
return ByteVector();
|
||||
}
|
||||
@@ -138,9 +124,8 @@ ByteVector RIFF::File::chunkName(unsigned int i) const
|
||||
return d->chunks[i].name;
|
||||
}
|
||||
|
||||
ByteVector RIFF::File::chunkData(unsigned int i)
|
||||
{
|
||||
if(i >= d->chunks.size()) {
|
||||
ByteVector RIFF::File::chunkData(unsigned int i) {
|
||||
if (i >= d->chunks.size()) {
|
||||
debug("RIFF::File::chunkData() - Index out of range. Returning an empty vector.");
|
||||
return ByteVector();
|
||||
}
|
||||
@@ -149,9 +134,8 @@ ByteVector RIFF::File::chunkData(unsigned int i)
|
||||
return readBlock(d->chunks[i].size);
|
||||
}
|
||||
|
||||
void RIFF::File::setChunkData(unsigned int i, const ByteVector &data)
|
||||
{
|
||||
if(i >= d->chunks.size()) {
|
||||
void RIFF::File::setChunkData(unsigned int i, const ByteVector &data) {
|
||||
if (i >= d->chunks.size()) {
|
||||
debug("RIFF::File::setChunkData() - Index out of range.");
|
||||
return;
|
||||
}
|
||||
@@ -165,14 +149,14 @@ void RIFF::File::setChunkData(unsigned int i, const ByteVector &data)
|
||||
|
||||
writeChunk(it->name, data, it->offset - 8, it->size + it->padding + 8);
|
||||
|
||||
it->size = data.size();
|
||||
it->size = data.size();
|
||||
it->padding = data.size() % 2;
|
||||
|
||||
const long long diff = static_cast<long long>(it->size) + it->padding - originalSize;
|
||||
|
||||
// Now update the internal offsets
|
||||
|
||||
for(++it; it != d->chunks.end(); ++it)
|
||||
for (++it; it != d->chunks.end(); ++it)
|
||||
it->offset += static_cast<int>(diff);
|
||||
|
||||
// Update the global size.
|
||||
@@ -180,26 +164,24 @@ void RIFF::File::setChunkData(unsigned int i, const ByteVector &data)
|
||||
updateGlobalSize();
|
||||
}
|
||||
|
||||
void RIFF::File::setChunkData(const ByteVector &name, const ByteVector &data)
|
||||
{
|
||||
void RIFF::File::setChunkData(const ByteVector &name, const ByteVector &data) {
|
||||
setChunkData(name, data, false);
|
||||
}
|
||||
|
||||
void RIFF::File::setChunkData(const ByteVector &name, const ByteVector &data, bool alwaysCreate)
|
||||
{
|
||||
if(d->chunks.empty()) {
|
||||
void RIFF::File::setChunkData(const ByteVector &name, const ByteVector &data, bool alwaysCreate) {
|
||||
if (d->chunks.empty()) {
|
||||
debug("RIFF::File::setChunkData - No valid chunks found.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(alwaysCreate && name != "LIST") {
|
||||
if (alwaysCreate && name != "LIST") {
|
||||
debug("RIFF::File::setChunkData - alwaysCreate should be used for only \"LIST\" chunks.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!alwaysCreate) {
|
||||
for(unsigned int i = 0; i < d->chunks.size(); i++) {
|
||||
if(d->chunks[i].name == name) {
|
||||
if (!alwaysCreate) {
|
||||
for (unsigned int i = 0; i < d->chunks.size(); i++) {
|
||||
if (d->chunks[i].name == name) {
|
||||
setChunkData(i, data);
|
||||
return;
|
||||
}
|
||||
@@ -213,9 +195,9 @@ void RIFF::File::setChunkData(const ByteVector &name, const ByteVector &data, bo
|
||||
Chunk &last = d->chunks.back();
|
||||
|
||||
long offset = last.offset + last.size + last.padding;
|
||||
if(offset & 1) {
|
||||
if(last.padding == 1) {
|
||||
last.padding = 0; // This should not happen unless the file is corrupted.
|
||||
if (offset & 1) {
|
||||
if (last.padding == 1) {
|
||||
last.padding = 0; // This should not happen unless the file is corrupted.
|
||||
offset--;
|
||||
removeBlock(offset, 1);
|
||||
}
|
||||
@@ -233,9 +215,9 @@ void RIFF::File::setChunkData(const ByteVector &name, const ByteVector &data, bo
|
||||
// And update our internal structure
|
||||
|
||||
Chunk chunk;
|
||||
chunk.name = name;
|
||||
chunk.size = data.size();
|
||||
chunk.offset = offset + 8;
|
||||
chunk.name = name;
|
||||
chunk.size = data.size();
|
||||
chunk.offset = offset + 8;
|
||||
chunk.padding = data.size() % 2;
|
||||
|
||||
d->chunks.push_back(chunk);
|
||||
@@ -245,9 +227,8 @@ void RIFF::File::setChunkData(const ByteVector &name, const ByteVector &data, bo
|
||||
updateGlobalSize();
|
||||
}
|
||||
|
||||
void RIFF::File::removeChunk(unsigned int i)
|
||||
{
|
||||
if(i >= d->chunks.size()) {
|
||||
void RIFF::File::removeChunk(unsigned int i) {
|
||||
if (i >= d->chunks.size()) {
|
||||
debug("RIFF::File::removeChunk() - Index out of range.");
|
||||
return;
|
||||
}
|
||||
@@ -259,7 +240,7 @@ void RIFF::File::removeChunk(unsigned int i)
|
||||
removeBlock(it->offset - 8, removeSize);
|
||||
it = d->chunks.erase(it);
|
||||
|
||||
for(; it != d->chunks.end(); ++it)
|
||||
for (; it != d->chunks.end(); ++it)
|
||||
it->offset -= removeSize;
|
||||
|
||||
// Update the global size.
|
||||
@@ -267,10 +248,9 @@ void RIFF::File::removeChunk(unsigned int i)
|
||||
updateGlobalSize();
|
||||
}
|
||||
|
||||
void RIFF::File::removeChunk(const ByteVector &name)
|
||||
{
|
||||
for(int i = static_cast<int>(d->chunks.size()) - 1; i >= 0; --i) {
|
||||
if(d->chunks[i].name == name)
|
||||
void RIFF::File::removeChunk(const ByteVector &name) {
|
||||
for (int i = static_cast<int>(d->chunks.size()) - 1; i >= 0; --i) {
|
||||
if (d->chunks[i].name == name)
|
||||
removeChunk(i);
|
||||
}
|
||||
}
|
||||
@@ -279,8 +259,7 @@ void RIFF::File::removeChunk(const ByteVector &name)
|
||||
// private members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void RIFF::File::read()
|
||||
{
|
||||
void RIFF::File::read() {
|
||||
const bool bigEndian = (d->endianness == BigEndian);
|
||||
|
||||
long offset = tell();
|
||||
@@ -294,48 +273,48 @@ void RIFF::File::read()
|
||||
offset += 8;
|
||||
|
||||
// + 8: chunk header at least, fix for additional junk bytes
|
||||
while(offset + 8 <= length()) {
|
||||
while (offset + 8 <= length()) {
|
||||
|
||||
seek(offset);
|
||||
const ByteVector chunkName = readBlock(4);
|
||||
const ByteVector chunkName = readBlock(4);
|
||||
const unsigned int chunkSize = readBlock(4).toUInt(bigEndian);
|
||||
|
||||
if(!isValidChunkName(chunkName)) {
|
||||
if (!isValidChunkName(chunkName)) {
|
||||
debug("RIFF::File::read() -- Chunk '" + chunkName + "' has invalid ID");
|
||||
setValid(false);
|
||||
break;
|
||||
}
|
||||
|
||||
if(static_cast<long long>(offset) + 8 + chunkSize > length()) {
|
||||
if (static_cast<long long>(offset) + 8 + chunkSize > length()) {
|
||||
debug("RIFF::File::read() -- Chunk '" + chunkName + "' has invalid size (larger than the file size)");
|
||||
setValid(false);
|
||||
break;
|
||||
}
|
||||
|
||||
Chunk chunk;
|
||||
chunk.name = chunkName;
|
||||
chunk.size = chunkSize;
|
||||
chunk.offset = offset + 8;
|
||||
chunk.name = chunkName;
|
||||
chunk.size = chunkSize;
|
||||
chunk.offset = offset + 8;
|
||||
chunk.padding = 0;
|
||||
|
||||
offset = chunk.offset + chunk.size;
|
||||
|
||||
// Check padding
|
||||
|
||||
if(offset & 1) {
|
||||
if (offset & 1) {
|
||||
seek(offset);
|
||||
const ByteVector iByte = readBlock(1);
|
||||
if(iByte.size() == 1) {
|
||||
if (iByte.size() == 1) {
|
||||
bool skipPadding = iByte[0] == '\0';
|
||||
if(!skipPadding) {
|
||||
if (!skipPadding) {
|
||||
// Padding byte is not zero, check if it is good to ignore it
|
||||
const ByteVector fourCcAfterPadding = readBlock(4);
|
||||
if(isValidChunkName(fourCcAfterPadding)) {
|
||||
if (isValidChunkName(fourCcAfterPadding)) {
|
||||
// Use the padding, it is followed by a valid chunk name.
|
||||
skipPadding = true;
|
||||
}
|
||||
}
|
||||
if(skipPadding) {
|
||||
if (skipPadding) {
|
||||
chunk.padding = 1;
|
||||
offset++;
|
||||
}
|
||||
@@ -347,24 +326,22 @@ void RIFF::File::read()
|
||||
}
|
||||
|
||||
void RIFF::File::writeChunk(const ByteVector &name, const ByteVector &data,
|
||||
unsigned long offset, unsigned long replace)
|
||||
{
|
||||
unsigned long offset, unsigned long replace) {
|
||||
ByteVector combined;
|
||||
|
||||
combined.append(name);
|
||||
combined.append(ByteVector::fromUInt(data.size(), d->endianness == BigEndian));
|
||||
combined.append(data);
|
||||
|
||||
if(data.size() & 1)
|
||||
if (data.size() & 1)
|
||||
combined.resize(combined.size() + 1, '\0');
|
||||
|
||||
insert(combined, offset, replace);
|
||||
}
|
||||
|
||||
void RIFF::File::updateGlobalSize()
|
||||
{
|
||||
void RIFF::File::updateGlobalSize() {
|
||||
const Chunk first = d->chunks.front();
|
||||
const Chunk last = d->chunks.back();
|
||||
const Chunk last = d->chunks.back();
|
||||
d->size = last.offset + last.size + last.padding - first.offset + 12;
|
||||
|
||||
const ByteVector data = ByteVector::fromUInt(d->size, d->endianness == BigEndian);
|
||||
|
||||
103
3rdparty/taglib/riff/rifffile.h
vendored
103
3rdparty/taglib/riff/rifffile.h
vendored
@@ -32,87 +32,86 @@
|
||||
namespace Strawberry_TagLib {
|
||||
namespace TagLib {
|
||||
|
||||
//! An implementation of TagLib::File with RIFF specific methods
|
||||
//! An implementation of TagLib::File with RIFF specific methods
|
||||
|
||||
namespace RIFF {
|
||||
namespace RIFF {
|
||||
|
||||
//! An RIFF file class with some useful methods specific to RIFF
|
||||
//! An RIFF file class with some useful methods specific to RIFF
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* This implements the generic TagLib::File API and additionally provides
|
||||
* access to properties that are distinct to RIFF files, notably access
|
||||
* to the different ID3 tags.
|
||||
*/
|
||||
|
||||
class TAGLIB_EXPORT File : public Strawberry_TagLib::TagLib::File
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
class TAGLIB_EXPORT File : public Strawberry_TagLib::TagLib::File {
|
||||
public:
|
||||
/*!
|
||||
* Destroys this instance of the File.
|
||||
*/
|
||||
virtual ~File();
|
||||
virtual ~File();
|
||||
|
||||
protected:
|
||||
protected:
|
||||
enum Endianness { BigEndian,
|
||||
LittleEndian };
|
||||
|
||||
enum Endianness { BigEndian, LittleEndian };
|
||||
File(FileName file, Endianness endianness);
|
||||
File(IOStream *stream, Endianness endianness);
|
||||
|
||||
File(FileName file, Endianness endianness);
|
||||
File(IOStream *stream, Endianness endianness);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \return The size of the main RIFF chunk.
|
||||
*/
|
||||
unsigned int riffSize() const;
|
||||
unsigned int riffSize() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \return The number of chunks in the file.
|
||||
*/
|
||||
unsigned int chunkCount() const;
|
||||
unsigned int chunkCount() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \return The offset within the file for the selected chunk number.
|
||||
*/
|
||||
unsigned int chunkOffset(unsigned int i) const;
|
||||
unsigned int chunkOffset(unsigned int i) const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \return The size of the chunk data.
|
||||
*/
|
||||
unsigned int chunkDataSize(unsigned int i) const;
|
||||
unsigned int chunkDataSize(unsigned int i) const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \return The size of the padding after the chunk (can be either 0 or 1).
|
||||
*/
|
||||
unsigned int chunkPadding(unsigned int i) const;
|
||||
unsigned int chunkPadding(unsigned int i) const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \return The name of the specified chunk, for instance, "COMM" or "ID3 "
|
||||
*/
|
||||
ByteVector chunkName(unsigned int i) const;
|
||||
ByteVector chunkName(unsigned int i) const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Reads the chunk data from the file and returns it.
|
||||
*
|
||||
* \note This \e will move the read pointer for the file.
|
||||
*/
|
||||
ByteVector chunkData(unsigned int i);
|
||||
ByteVector chunkData(unsigned int i);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Sets the data for the specified chunk to \a data.
|
||||
*
|
||||
* \warning This will update the file immediately.
|
||||
*/
|
||||
void setChunkData(unsigned int i, const ByteVector &data);
|
||||
void setChunkData(unsigned int i, const ByteVector &data);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Sets the data for the chunk \a name to \a data. If a chunk with the
|
||||
* given name already exists it will be overwritten, otherwise it will be
|
||||
* created after the existing chunks.
|
||||
*
|
||||
* \warning This will update the file immediately.
|
||||
*/
|
||||
void setChunkData(const ByteVector &name, const ByteVector &data);
|
||||
void setChunkData(const ByteVector &name, const ByteVector &data);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Sets the data for the chunk \a name to \a data. If a chunk with the
|
||||
* given name already exists it will be overwritten, otherwise it will be
|
||||
* created after the existing chunks.
|
||||
@@ -123,41 +122,41 @@ namespace TagLib {
|
||||
*
|
||||
* \warning This will update the file immediately.
|
||||
*/
|
||||
void setChunkData(const ByteVector &name, const ByteVector &data, bool alwaysCreate);
|
||||
void setChunkData(const ByteVector &name, const ByteVector &data, bool alwaysCreate);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Removes the specified chunk.
|
||||
*
|
||||
* \warning This will update the file immediately.
|
||||
*/
|
||||
void removeChunk(unsigned int i);
|
||||
void removeChunk(unsigned int i);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Removes the chunk \a name.
|
||||
*
|
||||
* \warning This will update the file immediately.
|
||||
* \warning This removes all the chunks with the given name.
|
||||
*/
|
||||
void removeChunk(const ByteVector &name);
|
||||
void removeChunk(const ByteVector &name);
|
||||
|
||||
private:
|
||||
File(const File &);
|
||||
File &operator=(const File &);
|
||||
private:
|
||||
File(const File &);
|
||||
File &operator=(const File &);
|
||||
|
||||
void read();
|
||||
void writeChunk(const ByteVector &name, const ByteVector &data,
|
||||
unsigned long offset, unsigned long replace = 0);
|
||||
void read();
|
||||
void writeChunk(const ByteVector &name, const ByteVector &data,
|
||||
unsigned long offset, unsigned long replace = 0);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Update the global RIFF size based on the current internal structure.
|
||||
*/
|
||||
void updateGlobalSize();
|
||||
void updateGlobalSize();
|
||||
|
||||
class FilePrivate;
|
||||
FilePrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
class FilePrivate;
|
||||
FilePrivate *d;
|
||||
};
|
||||
} // namespace RIFF
|
||||
} // namespace TagLib
|
||||
} // namespace Strawberry_TagLib
|
||||
|
||||
#endif
|
||||
|
||||
38
3rdparty/taglib/riff/riffutils.h
vendored
38
3rdparty/taglib/riff/riffutils.h
vendored
@@ -31,31 +31,27 @@
|
||||
#ifndef DO_NOT_DOCUMENT // tell Doxygen not to document this header
|
||||
|
||||
namespace Strawberry_TagLib {
|
||||
namespace TagLib
|
||||
{
|
||||
namespace RIFF
|
||||
{
|
||||
namespace
|
||||
{
|
||||
namespace TagLib {
|
||||
namespace RIFF {
|
||||
namespace {
|
||||
|
||||
inline bool isValidChunkName(const ByteVector &name)
|
||||
{
|
||||
if(name.size() != 4)
|
||||
return false;
|
||||
inline bool isValidChunkName(const ByteVector &name) {
|
||||
if (name.size() != 4)
|
||||
return false;
|
||||
|
||||
for(ByteVector::ConstIterator it = name.begin(); it != name.end(); ++it) {
|
||||
const int c = static_cast<unsigned char>(*it);
|
||||
if(c < 32 || 127 < c)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
for (ByteVector::ConstIterator it = name.begin(); it != name.end(); ++it) {
|
||||
const int c = static_cast<unsigned char>(*it);
|
||||
if (c < 32 || 127 < c)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace RIFF
|
||||
} // namespace TagLib
|
||||
} // namespace Strawberry_TagLib
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
135
3rdparty/taglib/riff/wav/infotag.cpp
vendored
135
3rdparty/taglib/riff/wav/infotag.cpp
vendored
@@ -32,15 +32,13 @@
|
||||
using namespace Strawberry_TagLib::TagLib;
|
||||
using namespace RIFF::Info;
|
||||
|
||||
namespace
|
||||
{
|
||||
const RIFF::Info::StringHandler defaultStringHandler;
|
||||
const RIFF::Info::StringHandler *stringHandler = &defaultStringHandler;
|
||||
}
|
||||
namespace {
|
||||
const RIFF::Info::StringHandler defaultStringHandler;
|
||||
const RIFF::Info::StringHandler *stringHandler = &defaultStringHandler;
|
||||
} // namespace
|
||||
|
||||
class RIFF::Info::Tag::TagPrivate
|
||||
{
|
||||
public:
|
||||
class RIFF::Info::Tag::TagPrivate {
|
||||
public:
|
||||
FieldListMap fieldListMap;
|
||||
};
|
||||
|
||||
@@ -48,21 +46,17 @@ public:
|
||||
// StringHandler implementation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
StringHandler::StringHandler()
|
||||
{
|
||||
StringHandler::StringHandler() {
|
||||
}
|
||||
|
||||
StringHandler::~StringHandler()
|
||||
{
|
||||
StringHandler::~StringHandler() {
|
||||
}
|
||||
|
||||
String RIFF::Info::StringHandler::parse(const ByteVector &data) const
|
||||
{
|
||||
String RIFF::Info::StringHandler::parse(const ByteVector &data) const {
|
||||
return String(data, String::UTF8);
|
||||
}
|
||||
|
||||
ByteVector RIFF::Info::StringHandler::render(const String &s) const
|
||||
{
|
||||
ByteVector RIFF::Info::StringHandler::render(const String &s) const {
|
||||
return s.data(String::UTF8);
|
||||
}
|
||||
|
||||
@@ -70,144 +64,119 @@ ByteVector RIFF::Info::StringHandler::render(const String &s) const
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
RIFF::Info::Tag::Tag(const ByteVector &data) :
|
||||
Strawberry_TagLib::TagLib::Tag(),
|
||||
d(new TagPrivate())
|
||||
{
|
||||
RIFF::Info::Tag::Tag(const ByteVector &data) : Strawberry_TagLib::TagLib::Tag(),
|
||||
d(new TagPrivate()) {
|
||||
parse(data);
|
||||
}
|
||||
|
||||
RIFF::Info::Tag::Tag() :
|
||||
Strawberry_TagLib::TagLib::Tag(),
|
||||
d(new TagPrivate())
|
||||
{
|
||||
RIFF::Info::Tag::Tag() : Strawberry_TagLib::TagLib::Tag(),
|
||||
d(new TagPrivate()) {
|
||||
}
|
||||
|
||||
RIFF::Info::Tag::~Tag()
|
||||
{
|
||||
RIFF::Info::Tag::~Tag() {
|
||||
delete d;
|
||||
}
|
||||
|
||||
String RIFF::Info::Tag::title() const
|
||||
{
|
||||
String RIFF::Info::Tag::title() const {
|
||||
return fieldText("INAM");
|
||||
}
|
||||
|
||||
String RIFF::Info::Tag::artist() const
|
||||
{
|
||||
String RIFF::Info::Tag::artist() const {
|
||||
return fieldText("IART");
|
||||
}
|
||||
|
||||
String RIFF::Info::Tag::album() const
|
||||
{
|
||||
String RIFF::Info::Tag::album() const {
|
||||
return fieldText("IPRD");
|
||||
}
|
||||
|
||||
String RIFF::Info::Tag::comment() const
|
||||
{
|
||||
String RIFF::Info::Tag::comment() const {
|
||||
return fieldText("ICMT");
|
||||
}
|
||||
|
||||
String RIFF::Info::Tag::genre() const
|
||||
{
|
||||
String RIFF::Info::Tag::genre() const {
|
||||
return fieldText("IGNR");
|
||||
}
|
||||
|
||||
unsigned int RIFF::Info::Tag::year() const
|
||||
{
|
||||
unsigned int RIFF::Info::Tag::year() const {
|
||||
return fieldText("ICRD").substr(0, 4).toInt();
|
||||
}
|
||||
|
||||
unsigned int RIFF::Info::Tag::track() const
|
||||
{
|
||||
unsigned int RIFF::Info::Tag::track() const {
|
||||
return fieldText("IPRT").toInt();
|
||||
}
|
||||
|
||||
void RIFF::Info::Tag::setTitle(const String &s)
|
||||
{
|
||||
void RIFF::Info::Tag::setTitle(const String &s) {
|
||||
setFieldText("INAM", s);
|
||||
}
|
||||
|
||||
void RIFF::Info::Tag::setArtist(const String &s)
|
||||
{
|
||||
void RIFF::Info::Tag::setArtist(const String &s) {
|
||||
setFieldText("IART", s);
|
||||
}
|
||||
|
||||
void RIFF::Info::Tag::setAlbum(const String &s)
|
||||
{
|
||||
void RIFF::Info::Tag::setAlbum(const String &s) {
|
||||
setFieldText("IPRD", s);
|
||||
}
|
||||
|
||||
void RIFF::Info::Tag::setComment(const String &s)
|
||||
{
|
||||
void RIFF::Info::Tag::setComment(const String &s) {
|
||||
setFieldText("ICMT", s);
|
||||
}
|
||||
|
||||
void RIFF::Info::Tag::setGenre(const String &s)
|
||||
{
|
||||
void RIFF::Info::Tag::setGenre(const String &s) {
|
||||
setFieldText("IGNR", s);
|
||||
}
|
||||
|
||||
void RIFF::Info::Tag::setYear(unsigned int i)
|
||||
{
|
||||
if(i != 0)
|
||||
void RIFF::Info::Tag::setYear(unsigned int i) {
|
||||
if (i != 0)
|
||||
setFieldText("ICRD", String::number(i));
|
||||
else
|
||||
d->fieldListMap.erase("ICRD");
|
||||
}
|
||||
|
||||
void RIFF::Info::Tag::setTrack(unsigned int i)
|
||||
{
|
||||
if(i != 0)
|
||||
void RIFF::Info::Tag::setTrack(unsigned int i) {
|
||||
if (i != 0)
|
||||
setFieldText("IPRT", String::number(i));
|
||||
else
|
||||
d->fieldListMap.erase("IPRT");
|
||||
}
|
||||
|
||||
bool RIFF::Info::Tag::isEmpty() const
|
||||
{
|
||||
bool RIFF::Info::Tag::isEmpty() const {
|
||||
return d->fieldListMap.isEmpty();
|
||||
}
|
||||
|
||||
FieldListMap RIFF::Info::Tag::fieldListMap() const
|
||||
{
|
||||
FieldListMap RIFF::Info::Tag::fieldListMap() const {
|
||||
return d->fieldListMap;
|
||||
}
|
||||
|
||||
String RIFF::Info::Tag::fieldText(const ByteVector &id) const
|
||||
{
|
||||
if(d->fieldListMap.contains(id))
|
||||
String RIFF::Info::Tag::fieldText(const ByteVector &id) const {
|
||||
if (d->fieldListMap.contains(id))
|
||||
return String(d->fieldListMap[id]);
|
||||
else
|
||||
return String();
|
||||
}
|
||||
|
||||
void RIFF::Info::Tag::setFieldText(const ByteVector &id, const String &s)
|
||||
{
|
||||
void RIFF::Info::Tag::setFieldText(const ByteVector &id, const String &s) {
|
||||
// id must be four-byte long pure ascii string.
|
||||
if(!isValidChunkName(id))
|
||||
if (!isValidChunkName(id))
|
||||
return;
|
||||
|
||||
if(!s.isEmpty())
|
||||
if (!s.isEmpty())
|
||||
d->fieldListMap[id] = s;
|
||||
else
|
||||
removeField(id);
|
||||
}
|
||||
|
||||
void RIFF::Info::Tag::removeField(const ByteVector &id)
|
||||
{
|
||||
if(d->fieldListMap.contains(id))
|
||||
void RIFF::Info::Tag::removeField(const ByteVector &id) {
|
||||
if (d->fieldListMap.contains(id))
|
||||
d->fieldListMap.erase(id);
|
||||
}
|
||||
|
||||
ByteVector RIFF::Info::Tag::render() const
|
||||
{
|
||||
ByteVector RIFF::Info::Tag::render() const {
|
||||
ByteVector data("INFO");
|
||||
|
||||
FieldListMap::ConstIterator it = d->fieldListMap.begin();
|
||||
for(; it != d->fieldListMap.end(); ++it) {
|
||||
for (; it != d->fieldListMap.end(); ++it) {
|
||||
ByteVector text = stringHandler->render(it->second);
|
||||
if(text.isEmpty())
|
||||
if (text.isEmpty())
|
||||
continue;
|
||||
|
||||
data.append(it->first);
|
||||
@@ -216,18 +185,17 @@ ByteVector RIFF::Info::Tag::render() const
|
||||
|
||||
do {
|
||||
data.append('\0');
|
||||
} while(data.size() & 1);
|
||||
} while (data.size() & 1);
|
||||
}
|
||||
|
||||
if(data.size() == 4)
|
||||
if (data.size() == 4)
|
||||
return ByteVector();
|
||||
else
|
||||
return data;
|
||||
}
|
||||
|
||||
void RIFF::Info::Tag::setStringHandler(const StringHandler *handler)
|
||||
{
|
||||
if(handler)
|
||||
void RIFF::Info::Tag::setStringHandler(const StringHandler *handler) {
|
||||
if (handler)
|
||||
stringHandler = handler;
|
||||
else
|
||||
stringHandler = &defaultStringHandler;
|
||||
@@ -237,16 +205,15 @@ void RIFF::Info::Tag::setStringHandler(const StringHandler *handler)
|
||||
// protected members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void RIFF::Info::Tag::parse(const ByteVector &data)
|
||||
{
|
||||
void RIFF::Info::Tag::parse(const ByteVector &data) {
|
||||
unsigned int p = 4;
|
||||
while(p < data.size()) {
|
||||
while (p < data.size()) {
|
||||
const unsigned int size = data.toUInt(p + 4, false);
|
||||
if(size > data.size() - p - 8)
|
||||
if (size > data.size() - p - 8)
|
||||
break;
|
||||
|
||||
const ByteVector id = data.mid(p, 4);
|
||||
if(isValidChunkName(id)) {
|
||||
if (isValidChunkName(id)) {
|
||||
const String text = stringHandler->parse(data.mid(p + 8, size));
|
||||
d->fieldListMap[id] = text;
|
||||
}
|
||||
|
||||
133
3rdparty/taglib/riff/wav/infotag.h
vendored
133
3rdparty/taglib/riff/wav/infotag.h
vendored
@@ -36,17 +36,17 @@
|
||||
namespace Strawberry_TagLib {
|
||||
namespace TagLib {
|
||||
|
||||
class File;
|
||||
class File;
|
||||
|
||||
//! A RIFF INFO tag implementation.
|
||||
namespace RIFF {
|
||||
namespace Info {
|
||||
//! A RIFF INFO tag implementation.
|
||||
namespace RIFF {
|
||||
namespace Info {
|
||||
|
||||
typedef Map<ByteVector, String> FieldListMap;
|
||||
typedef Map<ByteVector, String> FieldListMap;
|
||||
|
||||
//! A abstraction for the string to data encoding in Info tags.
|
||||
//! A abstraction for the string to data encoding in Info tags.
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* RIFF INFO tag has no clear definitions about character encodings.
|
||||
* In practice, local encoding of each system is largely used and UTF-8 is
|
||||
* popular too.
|
||||
@@ -58,70 +58,68 @@ namespace TagLib {
|
||||
* \see ID3v1::Tag::setStringHandler()
|
||||
*/
|
||||
|
||||
class TAGLIB_EXPORT StringHandler
|
||||
{
|
||||
public:
|
||||
StringHandler();
|
||||
~StringHandler();
|
||||
class TAGLIB_EXPORT StringHandler {
|
||||
public:
|
||||
StringHandler();
|
||||
~StringHandler();
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Decode a string from \a data. The default implementation assumes that
|
||||
* \a data is an UTF-8 character array.
|
||||
*/
|
||||
virtual String parse(const ByteVector &data) const;
|
||||
virtual String parse(const ByteVector &data) const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Encode a ByteVector with the data from \a s. The default implementation
|
||||
* assumes that \a s is an UTF-8 string.
|
||||
*/
|
||||
virtual ByteVector render(const String &s) const;
|
||||
};
|
||||
virtual ByteVector render(const String &s) const;
|
||||
};
|
||||
|
||||
//! The main class in the ID3v2 implementation
|
||||
//! The main class in the ID3v2 implementation
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* This is the main class in the INFO tag implementation. RIFF INFO tag is a
|
||||
* metadata format found in WAV audio and AVI video files. Though it is a part
|
||||
* of Microsoft/IBM's RIFF specification, the author could not find the official
|
||||
* documents about it. So, this implementation is referring to unofficial documents
|
||||
* online and some applications' behaviors especially Windows Explorer.
|
||||
*/
|
||||
class TAGLIB_EXPORT Tag : public Strawberry_TagLib::TagLib::Tag
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
class TAGLIB_EXPORT Tag : public Strawberry_TagLib::TagLib::Tag {
|
||||
public:
|
||||
/*!
|
||||
* Constructs an empty INFO tag.
|
||||
*/
|
||||
Tag();
|
||||
Tag();
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Constructs an INFO tag read from \a data which is contents of "LIST" chunk.
|
||||
*/
|
||||
Tag(const ByteVector &data);
|
||||
Tag(const ByteVector &data);
|
||||
|
||||
virtual ~Tag();
|
||||
virtual ~Tag();
|
||||
|
||||
// Reimplementations
|
||||
// Reimplementations
|
||||
|
||||
virtual String title() const;
|
||||
virtual String artist() const;
|
||||
virtual String album() const;
|
||||
virtual String comment() const;
|
||||
virtual String genre() const;
|
||||
virtual unsigned int year() const;
|
||||
virtual unsigned int track() const;
|
||||
virtual String title() const;
|
||||
virtual String artist() const;
|
||||
virtual String album() const;
|
||||
virtual String comment() const;
|
||||
virtual String genre() const;
|
||||
virtual unsigned int year() const;
|
||||
virtual unsigned int track() const;
|
||||
|
||||
virtual void setTitle(const String &s);
|
||||
virtual void setArtist(const String &s);
|
||||
virtual void setAlbum(const String &s);
|
||||
virtual void setComment(const String &s);
|
||||
virtual void setGenre(const String &s);
|
||||
virtual void setYear(unsigned int i);
|
||||
virtual void setTrack(unsigned int i);
|
||||
virtual void setTitle(const String &s);
|
||||
virtual void setArtist(const String &s);
|
||||
virtual void setAlbum(const String &s);
|
||||
virtual void setComment(const String &s);
|
||||
virtual void setGenre(const String &s);
|
||||
virtual void setYear(unsigned int i);
|
||||
virtual void setTrack(unsigned int i);
|
||||
|
||||
virtual bool isEmpty() const;
|
||||
virtual bool isEmpty() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns a copy of the internal fields of the tag. The returned map directly
|
||||
* reflects the contents of the "INFO" chunk.
|
||||
*
|
||||
@@ -131,14 +129,14 @@ namespace TagLib {
|
||||
* \see setFieldText()
|
||||
* \see removeField()
|
||||
*/
|
||||
FieldListMap fieldListMap() const;
|
||||
FieldListMap fieldListMap() const;
|
||||
|
||||
/*
|
||||
/*
|
||||
* Gets the value of the field with the ID \a id.
|
||||
*/
|
||||
String fieldText(const ByteVector &id) const;
|
||||
String fieldText(const ByteVector &id) const;
|
||||
|
||||
/*
|
||||
/*
|
||||
* Sets the value of the field with the ID \a id to \a s.
|
||||
* If the field does not exist, it is created.
|
||||
* If \s is empty, the field is removed.
|
||||
@@ -146,21 +144,21 @@ namespace TagLib {
|
||||
* \note fieldId must be four-byte long pure ASCII string. This function
|
||||
* performs nothing if fieldId is invalid.
|
||||
*/
|
||||
void setFieldText(const ByteVector &id, const String &s);
|
||||
void setFieldText(const ByteVector &id, const String &s);
|
||||
|
||||
/*
|
||||
/*
|
||||
* Removes the field with the ID \a id.
|
||||
*/
|
||||
void removeField(const ByteVector &id);
|
||||
void removeField(const ByteVector &id);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Render the tag back to binary data, suitable to be written to disk.
|
||||
*
|
||||
* \note Returns empty ByteVector is the tag contains no fields.
|
||||
*/
|
||||
ByteVector render() const;
|
||||
ByteVector render() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Sets the string handler that decides how the text data will be
|
||||
* converted to and from binary data.
|
||||
* If the parameter \a handler is null, the previous handler is
|
||||
@@ -171,24 +169,25 @@ namespace TagLib {
|
||||
*
|
||||
* \see StringHandler
|
||||
*/
|
||||
static void setStringHandler(const StringHandler *handler);
|
||||
static void setStringHandler(const StringHandler *handler);
|
||||
|
||||
protected:
|
||||
/*!
|
||||
protected:
|
||||
/*!
|
||||
* Pareses the body of the tag in \a data.
|
||||
*/
|
||||
void parse(const ByteVector &data);
|
||||
void parse(const ByteVector &data);
|
||||
|
||||
|
||||
private:
|
||||
Tag(const Tag &);
|
||||
Tag &operator=(const Tag &);
|
||||
private:
|
||||
Tag(const Tag &);
|
||||
Tag &operator=(const Tag &);
|
||||
|
||||
class TagPrivate;
|
||||
TagPrivate *d;
|
||||
};
|
||||
}}
|
||||
}
|
||||
}
|
||||
class TagPrivate;
|
||||
TagPrivate *d;
|
||||
};
|
||||
} // namespace Info
|
||||
} // namespace RIFF
|
||||
} // namespace TagLib
|
||||
} // namespace Strawberry_TagLib
|
||||
|
||||
#endif
|
||||
|
||||
136
3rdparty/taglib/riff/wav/wavfile.cpp
vendored
136
3rdparty/taglib/riff/wav/wavfile.cpp
vendored
@@ -36,21 +36,18 @@
|
||||
|
||||
using namespace Strawberry_TagLib::TagLib;
|
||||
|
||||
namespace
|
||||
{
|
||||
enum { ID3v2Index = 0, InfoIndex = 1 };
|
||||
namespace {
|
||||
enum { ID3v2Index = 0,
|
||||
InfoIndex = 1 };
|
||||
}
|
||||
|
||||
class RIFF::WAV::File::FilePrivate
|
||||
{
|
||||
public:
|
||||
FilePrivate() :
|
||||
properties(0),
|
||||
hasID3v2(false),
|
||||
hasInfo(false) {}
|
||||
class RIFF::WAV::File::FilePrivate {
|
||||
public:
|
||||
FilePrivate() : properties(0),
|
||||
hasID3v2(false),
|
||||
hasInfo(false) {}
|
||||
|
||||
~FilePrivate()
|
||||
{
|
||||
~FilePrivate() {
|
||||
delete properties;
|
||||
}
|
||||
|
||||
@@ -65,8 +62,7 @@ public:
|
||||
// static members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool RIFF::WAV::File::isSupported(IOStream *stream)
|
||||
{
|
||||
bool RIFF::WAV::File::isSupported(IOStream *stream) {
|
||||
// A WAV file has to start with "RIFF????WAVE".
|
||||
|
||||
const ByteVector id = Utils::readHeader(stream, 12, false);
|
||||
@@ -77,114 +73,98 @@ bool RIFF::WAV::File::isSupported(IOStream *stream)
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
RIFF::WAV::File::File(FileName file, bool readProperties, Properties::ReadStyle) :
|
||||
RIFF::File(file, LittleEndian),
|
||||
d(new FilePrivate())
|
||||
{
|
||||
if(isOpen())
|
||||
RIFF::WAV::File::File(FileName file, bool readProperties, Properties::ReadStyle) : RIFF::File(file, LittleEndian),
|
||||
d(new FilePrivate()) {
|
||||
if (isOpen())
|
||||
read(readProperties);
|
||||
}
|
||||
|
||||
RIFF::WAV::File::File(IOStream *stream, bool readProperties, Properties::ReadStyle) :
|
||||
RIFF::File(stream, LittleEndian),
|
||||
d(new FilePrivate())
|
||||
{
|
||||
if(isOpen())
|
||||
RIFF::WAV::File::File(IOStream *stream, bool readProperties, Properties::ReadStyle) : RIFF::File(stream, LittleEndian),
|
||||
d(new FilePrivate()) {
|
||||
if (isOpen())
|
||||
read(readProperties);
|
||||
}
|
||||
|
||||
RIFF::WAV::File::~File()
|
||||
{
|
||||
RIFF::WAV::File::~File() {
|
||||
delete d;
|
||||
}
|
||||
|
||||
ID3v2::Tag *RIFF::WAV::File::tag() const
|
||||
{
|
||||
ID3v2::Tag *RIFF::WAV::File::tag() const {
|
||||
return ID3v2Tag();
|
||||
}
|
||||
|
||||
ID3v2::Tag *RIFF::WAV::File::ID3v2Tag() const
|
||||
{
|
||||
ID3v2::Tag *RIFF::WAV::File::ID3v2Tag() const {
|
||||
return d->tag.access<ID3v2::Tag>(ID3v2Index, false);
|
||||
}
|
||||
|
||||
RIFF::Info::Tag *RIFF::WAV::File::InfoTag() const
|
||||
{
|
||||
RIFF::Info::Tag *RIFF::WAV::File::InfoTag() const {
|
||||
return d->tag.access<RIFF::Info::Tag>(InfoIndex, false);
|
||||
}
|
||||
|
||||
void RIFF::WAV::File::strip(TagTypes tags)
|
||||
{
|
||||
void RIFF::WAV::File::strip(TagTypes tags) {
|
||||
removeTagChunks(tags);
|
||||
|
||||
if(tags & ID3v2)
|
||||
if (tags & ID3v2)
|
||||
d->tag.set(ID3v2Index, new ID3v2::Tag());
|
||||
|
||||
if(tags & Info)
|
||||
if (tags & Info)
|
||||
d->tag.set(InfoIndex, new RIFF::Info::Tag());
|
||||
}
|
||||
|
||||
PropertyMap RIFF::WAV::File::properties() const
|
||||
{
|
||||
PropertyMap RIFF::WAV::File::properties() const {
|
||||
return d->tag.properties();
|
||||
}
|
||||
|
||||
void RIFF::WAV::File::removeUnsupportedProperties(const StringList &unsupported)
|
||||
{
|
||||
void RIFF::WAV::File::removeUnsupportedProperties(const StringList &unsupported) {
|
||||
d->tag.removeUnsupportedProperties(unsupported);
|
||||
}
|
||||
|
||||
PropertyMap RIFF::WAV::File::setProperties(const PropertyMap &properties)
|
||||
{
|
||||
PropertyMap RIFF::WAV::File::setProperties(const PropertyMap &properties) {
|
||||
InfoTag()->setProperties(properties);
|
||||
return ID3v2Tag()->setProperties(properties);
|
||||
}
|
||||
|
||||
RIFF::WAV::Properties *RIFF::WAV::File::audioProperties() const
|
||||
{
|
||||
RIFF::WAV::Properties *RIFF::WAV::File::audioProperties() const {
|
||||
return d->properties;
|
||||
}
|
||||
|
||||
bool RIFF::WAV::File::save()
|
||||
{
|
||||
bool RIFF::WAV::File::save() {
|
||||
return RIFF::WAV::File::save(AllTags);
|
||||
}
|
||||
|
||||
bool RIFF::WAV::File::save(TagTypes tags, bool stripOthers, int id3v2Version)
|
||||
{
|
||||
bool RIFF::WAV::File::save(TagTypes tags, bool stripOthers, int id3v2Version) {
|
||||
return save(tags,
|
||||
stripOthers ? StripOthers : StripNone,
|
||||
id3v2Version == 3 ? ID3v2::v3 : ID3v2::v4);
|
||||
stripOthers ? StripOthers : StripNone,
|
||||
id3v2Version == 3 ? ID3v2::v3 : ID3v2::v4);
|
||||
}
|
||||
|
||||
bool RIFF::WAV::File::save(TagTypes tags, StripTags strip, ID3v2::Version version)
|
||||
{
|
||||
if(readOnly()) {
|
||||
bool RIFF::WAV::File::save(TagTypes tags, StripTags strip, ID3v2::Version version) {
|
||||
if (readOnly()) {
|
||||
debug("RIFF::WAV::File::save() -- File is read only.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!isValid()) {
|
||||
if (!isValid()) {
|
||||
debug("RIFF::WAV::File::save() -- Trying to save invalid file.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(strip == StripOthers)
|
||||
if (strip == StripOthers)
|
||||
File::strip(static_cast<TagTypes>(AllTags & ~tags));
|
||||
|
||||
if(tags & ID3v2) {
|
||||
if (tags & ID3v2) {
|
||||
removeTagChunks(ID3v2);
|
||||
|
||||
if(ID3v2Tag() && !ID3v2Tag()->isEmpty()) {
|
||||
if (ID3v2Tag() && !ID3v2Tag()->isEmpty()) {
|
||||
setChunkData("ID3 ", ID3v2Tag()->render(version));
|
||||
d->hasID3v2 = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(tags & Info) {
|
||||
if (tags & Info) {
|
||||
removeTagChunks(Info);
|
||||
|
||||
if(InfoTag() && !InfoTag()->isEmpty()) {
|
||||
if (InfoTag() && !InfoTag()->isEmpty()) {
|
||||
setChunkData("LIST", InfoTag()->render(), true);
|
||||
d->hasInfo = true;
|
||||
}
|
||||
@@ -193,13 +173,11 @@ bool RIFF::WAV::File::save(TagTypes tags, StripTags strip, ID3v2::Version versio
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RIFF::WAV::File::hasID3v2Tag() const
|
||||
{
|
||||
bool RIFF::WAV::File::hasID3v2Tag() const {
|
||||
return d->hasID3v2;
|
||||
}
|
||||
|
||||
bool RIFF::WAV::File::hasInfoTag() const
|
||||
{
|
||||
bool RIFF::WAV::File::hasInfoTag() const {
|
||||
return d->hasInfo;
|
||||
}
|
||||
|
||||
@@ -207,12 +185,11 @@ bool RIFF::WAV::File::hasInfoTag() const
|
||||
// private members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void RIFF::WAV::File::read(bool readProperties)
|
||||
{
|
||||
for(unsigned int i = 0; i < chunkCount(); ++i) {
|
||||
void RIFF::WAV::File::read(bool readProperties) {
|
||||
for (unsigned int i = 0; i < chunkCount(); ++i) {
|
||||
const ByteVector name = chunkName(i);
|
||||
if(name == "ID3 " || name == "id3 ") {
|
||||
if(!d->tag[ID3v2Index]) {
|
||||
if (name == "ID3 " || name == "id3 ") {
|
||||
if (!d->tag[ID3v2Index]) {
|
||||
d->tag.set(ID3v2Index, new ID3v2::Tag(this, chunkOffset(i)));
|
||||
d->hasID3v2 = true;
|
||||
}
|
||||
@@ -220,10 +197,10 @@ void RIFF::WAV::File::read(bool readProperties)
|
||||
debug("RIFF::WAV::File::read() - Duplicate ID3v2 tag found.");
|
||||
}
|
||||
}
|
||||
else if(name == "LIST") {
|
||||
else if (name == "LIST") {
|
||||
const ByteVector data = chunkData(i);
|
||||
if(data.startsWith("INFO")) {
|
||||
if(!d->tag[InfoIndex]) {
|
||||
if (data.startsWith("INFO")) {
|
||||
if (!d->tag[InfoIndex]) {
|
||||
d->tag.set(InfoIndex, new RIFF::Info::Tag(data));
|
||||
d->hasInfo = true;
|
||||
}
|
||||
@@ -234,28 +211,27 @@ void RIFF::WAV::File::read(bool readProperties)
|
||||
}
|
||||
}
|
||||
|
||||
if(!d->tag[ID3v2Index])
|
||||
if (!d->tag[ID3v2Index])
|
||||
d->tag.set(ID3v2Index, new ID3v2::Tag());
|
||||
|
||||
if(!d->tag[InfoIndex])
|
||||
if (!d->tag[InfoIndex])
|
||||
d->tag.set(InfoIndex, new RIFF::Info::Tag());
|
||||
|
||||
if(readProperties)
|
||||
if (readProperties)
|
||||
d->properties = new Properties(this, Properties::Average);
|
||||
}
|
||||
|
||||
void RIFF::WAV::File::removeTagChunks(TagTypes tags)
|
||||
{
|
||||
if((tags & ID3v2) && d->hasID3v2) {
|
||||
void RIFF::WAV::File::removeTagChunks(TagTypes tags) {
|
||||
if ((tags & ID3v2) && d->hasID3v2) {
|
||||
removeChunk("ID3 ");
|
||||
removeChunk("id3 ");
|
||||
|
||||
d->hasID3v2 = false;
|
||||
}
|
||||
|
||||
if((tags & Info) && d->hasInfo) {
|
||||
for(int i = static_cast<int>(chunkCount()) - 1; i >= 0; --i) {
|
||||
if(chunkName(i) == "LIST" && chunkData(i).startsWith("INFO"))
|
||||
if ((tags & Info) && d->hasInfo) {
|
||||
for (int i = static_cast<int>(chunkCount()) - 1; i >= 0; --i) {
|
||||
if (chunkName(i) == "LIST" && chunkData(i).startsWith("INFO"))
|
||||
removeChunk(i);
|
||||
}
|
||||
|
||||
|
||||
135
3rdparty/taglib/riff/wav/wavfile.h
vendored
135
3rdparty/taglib/riff/wav/wavfile.h
vendored
@@ -34,52 +34,51 @@
|
||||
namespace Strawberry_TagLib {
|
||||
namespace TagLib {
|
||||
|
||||
namespace RIFF {
|
||||
namespace RIFF {
|
||||
|
||||
//! An implementation of WAV metadata
|
||||
//! An implementation of WAV metadata
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* This is implementation of WAV metadata.
|
||||
*
|
||||
* This supports an ID3v2 tag as well as reading stream from the ID3 RIFF
|
||||
* chunk as well as properties from the file.
|
||||
*/
|
||||
|
||||
namespace WAV {
|
||||
namespace WAV {
|
||||
|
||||
//! An implementation of TagLib::File with WAV specific methods
|
||||
//! An implementation of TagLib::File with WAV specific methods
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* This implements and provides an interface for WAV files to the
|
||||
* TagLib::Tag and TagLib::AudioProperties interfaces by way of implementing
|
||||
* the abstract TagLib::File API as well as providing some additional
|
||||
* information specific to WAV files.
|
||||
*/
|
||||
|
||||
class TAGLIB_EXPORT File : public Strawberry_TagLib::TagLib::RIFF::File
|
||||
{
|
||||
public:
|
||||
enum TagTypes {
|
||||
//! Empty set. Matches no tag types.
|
||||
NoTags = 0x0000,
|
||||
//! Matches ID3v2 tags.
|
||||
ID3v2 = 0x0001,
|
||||
//! Matches INFO tags.
|
||||
Info = 0x0002,
|
||||
//! Matches all tag types.
|
||||
AllTags = 0xffff
|
||||
};
|
||||
class TAGLIB_EXPORT File : public Strawberry_TagLib::TagLib::RIFF::File {
|
||||
public:
|
||||
enum TagTypes {
|
||||
//! Empty set. Matches no tag types.
|
||||
NoTags = 0x0000,
|
||||
//! Matches ID3v2 tags.
|
||||
ID3v2 = 0x0001,
|
||||
//! Matches INFO tags.
|
||||
Info = 0x0002,
|
||||
//! Matches all tag types.
|
||||
AllTags = 0xffff
|
||||
};
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Constructs a WAV 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 a WAV file from \a stream. If \a readProperties is true the
|
||||
* file's audio properties will also be read.
|
||||
*
|
||||
@@ -88,23 +87,23 @@ 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 ID3v2 Tag for this file.
|
||||
*
|
||||
* \note This method does not return all the tags for this file for
|
||||
* backward compatibility. Will be fixed in TagLib 2.0.
|
||||
*/
|
||||
ID3v2::Tag *tag() const;
|
||||
ID3v2::Tag *tag() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns the ID3v2 Tag for this file.
|
||||
*
|
||||
* \note This always returns a valid pointer regardless of whether or not
|
||||
@@ -113,9 +112,9 @@ namespace TagLib {
|
||||
*
|
||||
* \see hasID3v2Tag()
|
||||
*/
|
||||
ID3v2::Tag *ID3v2Tag() const;
|
||||
ID3v2::Tag *ID3v2Tag() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns the RIFF INFO Tag for this file.
|
||||
*
|
||||
* \note This always returns a valid pointer regardless of whether or not
|
||||
@@ -124,94 +123,94 @@ namespace TagLib {
|
||||
*
|
||||
* \see hasInfoTag()
|
||||
*/
|
||||
Info::Tag *InfoTag() const;
|
||||
Info::Tag *InfoTag() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* This will strip the tags that match the OR-ed together TagTypes from the
|
||||
* file. By default it strips all tags. It returns true if the tags are
|
||||
* successfully stripped.
|
||||
*
|
||||
* \note This will update the file immediately.
|
||||
*/
|
||||
void strip(TagTypes tags = AllTags);
|
||||
void strip(TagTypes tags = AllTags);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Implements the unified property interface -- export function.
|
||||
* This method forwards to ID3v2::Tag::properties().
|
||||
*/
|
||||
PropertyMap properties() const;
|
||||
PropertyMap properties() const;
|
||||
|
||||
void removeUnsupportedProperties(const StringList &properties);
|
||||
void removeUnsupportedProperties(const StringList &properties);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Implements the unified property interface -- import function.
|
||||
* This method forwards to ID3v2::Tag::setProperties().
|
||||
*/
|
||||
PropertyMap setProperties(const PropertyMap &);
|
||||
PropertyMap setProperties(const PropertyMap &);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns the WAV::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.
|
||||
*/
|
||||
virtual bool save();
|
||||
virtual bool save();
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* \deprecated
|
||||
*/
|
||||
TAGLIB_DEPRECATED bool save(TagTypes tags, bool stripOthers, int id3v2Version = 4);
|
||||
TAGLIB_DEPRECATED bool save(TagTypes tags, bool stripOthers, int id3v2Version = 4);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Save the file. If \a strip is specified, it is possible to choose if
|
||||
* tags not specified in \a tags should be stripped from the file or
|
||||
* retained. With \a version, it is possible to specify whether ID3v2.4
|
||||
* or ID3v2.3 should be used.
|
||||
*/
|
||||
bool save(TagTypes tags, StripTags strip = StripOthers,
|
||||
ID3v2::Version version = ID3v2::v4);
|
||||
bool save(TagTypes tags, StripTags strip = StripOthers,
|
||||
ID3v2::Version version = ID3v2::v4);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns whether or not the file on disk actually has an ID3v2 tag.
|
||||
*
|
||||
* \see ID3v2Tag()
|
||||
*/
|
||||
bool hasID3v2Tag() const;
|
||||
bool hasID3v2Tag() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns whether or not the file on disk actually has a RIFF INFO tag.
|
||||
*
|
||||
* \see InfoTag()
|
||||
*/
|
||||
bool hasInfoTag() const;
|
||||
bool hasInfoTag() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns whether or not the given \a stream can be opened as a WAV
|
||||
* 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 removeTagChunks(TagTypes tags);
|
||||
void read(bool readProperties);
|
||||
void removeTagChunks(TagTypes tags);
|
||||
|
||||
friend class Properties;
|
||||
friend class Properties;
|
||||
|
||||
class FilePrivate;
|
||||
FilePrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
class FilePrivate;
|
||||
FilePrivate *d;
|
||||
};
|
||||
} // namespace WAV
|
||||
} // namespace RIFF
|
||||
} // namespace TagLib
|
||||
} // namespace Strawberry_TagLib
|
||||
|
||||
#endif
|
||||
|
||||
126
3rdparty/taglib/riff/wav/wavproperties.cpp
vendored
126
3rdparty/taglib/riff/wav/wavproperties.cpp
vendored
@@ -29,27 +29,23 @@
|
||||
|
||||
using namespace Strawberry_TagLib::TagLib;
|
||||
|
||||
namespace
|
||||
{
|
||||
// Quoted from RFC 2361.
|
||||
enum WaveFormat
|
||||
{
|
||||
FORMAT_UNKNOWN = 0x0000,
|
||||
FORMAT_PCM = 0x0001
|
||||
};
|
||||
}
|
||||
namespace {
|
||||
// Quoted from RFC 2361.
|
||||
enum WaveFormat {
|
||||
FORMAT_UNKNOWN = 0x0000,
|
||||
FORMAT_PCM = 0x0001
|
||||
};
|
||||
} // namespace
|
||||
|
||||
class RIFF::WAV::Properties::PropertiesPrivate
|
||||
{
|
||||
public:
|
||||
PropertiesPrivate() :
|
||||
format(0),
|
||||
length(0),
|
||||
bitrate(0),
|
||||
sampleRate(0),
|
||||
channels(0),
|
||||
bitsPerSample(0),
|
||||
sampleFrames(0) {}
|
||||
class RIFF::WAV::Properties::PropertiesPrivate {
|
||||
public:
|
||||
PropertiesPrivate() : format(0),
|
||||
length(0),
|
||||
bitrate(0),
|
||||
sampleRate(0),
|
||||
channels(0),
|
||||
bitsPerSample(0),
|
||||
sampleFrames(0) {}
|
||||
|
||||
int format;
|
||||
int length;
|
||||
@@ -64,79 +60,62 @@ public:
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
RIFF::WAV::Properties::Properties(const ByteVector &, ReadStyle style) :
|
||||
AudioProperties(style),
|
||||
d(new PropertiesPrivate())
|
||||
{
|
||||
RIFF::WAV::Properties::Properties(const ByteVector &, ReadStyle style) : AudioProperties(style),
|
||||
d(new PropertiesPrivate()) {
|
||||
debug("RIFF::WAV::Properties::Properties() -- This constructor is no longer used.");
|
||||
}
|
||||
|
||||
RIFF::WAV::Properties::Properties(const ByteVector &, unsigned int, ReadStyle style) :
|
||||
AudioProperties(style),
|
||||
d(new PropertiesPrivate())
|
||||
{
|
||||
RIFF::WAV::Properties::Properties(const ByteVector &, unsigned int, ReadStyle style) : AudioProperties(style),
|
||||
d(new PropertiesPrivate()) {
|
||||
debug("RIFF::WAV::Properties::Properties() -- This constructor is no longer used.");
|
||||
}
|
||||
|
||||
Strawberry_TagLib::TagLib::RIFF::WAV::Properties::Properties(File *file, ReadStyle style) :
|
||||
AudioProperties(style),
|
||||
d(new PropertiesPrivate())
|
||||
{
|
||||
Strawberry_TagLib::TagLib::RIFF::WAV::Properties::Properties(File *file, ReadStyle style) : AudioProperties(style),
|
||||
d(new PropertiesPrivate()) {
|
||||
read(file);
|
||||
}
|
||||
|
||||
RIFF::WAV::Properties::~Properties()
|
||||
{
|
||||
RIFF::WAV::Properties::~Properties() {
|
||||
delete d;
|
||||
}
|
||||
|
||||
int RIFF::WAV::Properties::length() const
|
||||
{
|
||||
int RIFF::WAV::Properties::length() const {
|
||||
return lengthInSeconds();
|
||||
}
|
||||
|
||||
int RIFF::WAV::Properties::lengthInSeconds() const
|
||||
{
|
||||
int RIFF::WAV::Properties::lengthInSeconds() const {
|
||||
return d->length / 1000;
|
||||
}
|
||||
|
||||
int RIFF::WAV::Properties::lengthInMilliseconds() const
|
||||
{
|
||||
int RIFF::WAV::Properties::lengthInMilliseconds() const {
|
||||
return d->length;
|
||||
}
|
||||
|
||||
int RIFF::WAV::Properties::bitrate() const
|
||||
{
|
||||
int RIFF::WAV::Properties::bitrate() const {
|
||||
return d->bitrate;
|
||||
}
|
||||
|
||||
int RIFF::WAV::Properties::sampleRate() const
|
||||
{
|
||||
int RIFF::WAV::Properties::sampleRate() const {
|
||||
return d->sampleRate;
|
||||
}
|
||||
|
||||
int RIFF::WAV::Properties::channels() const
|
||||
{
|
||||
int RIFF::WAV::Properties::channels() const {
|
||||
return d->channels;
|
||||
}
|
||||
|
||||
int RIFF::WAV::Properties::bitsPerSample() const
|
||||
{
|
||||
int RIFF::WAV::Properties::bitsPerSample() const {
|
||||
return d->bitsPerSample;
|
||||
}
|
||||
|
||||
int RIFF::WAV::Properties::sampleWidth() const
|
||||
{
|
||||
int RIFF::WAV::Properties::sampleWidth() const {
|
||||
return bitsPerSample();
|
||||
}
|
||||
|
||||
unsigned int RIFF::WAV::Properties::sampleFrames() const
|
||||
{
|
||||
unsigned int RIFF::WAV::Properties::sampleFrames() const {
|
||||
return d->sampleFrames;
|
||||
}
|
||||
|
||||
int RIFF::WAV::Properties::format() const
|
||||
{
|
||||
int RIFF::WAV::Properties::format() const {
|
||||
return d->format;
|
||||
}
|
||||
|
||||
@@ -144,68 +123,67 @@ int RIFF::WAV::Properties::format() const
|
||||
// private members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void RIFF::WAV::Properties::read(File *file)
|
||||
{
|
||||
void RIFF::WAV::Properties::read(File *file) {
|
||||
ByteVector data;
|
||||
unsigned int streamLength = 0;
|
||||
unsigned int totalSamples = 0;
|
||||
|
||||
for(unsigned int i = 0; i < file->chunkCount(); ++i) {
|
||||
for (unsigned int i = 0; i < file->chunkCount(); ++i) {
|
||||
const ByteVector name = file->chunkName(i);
|
||||
if(name == "fmt ") {
|
||||
if(data.isEmpty())
|
||||
if (name == "fmt ") {
|
||||
if (data.isEmpty())
|
||||
data = file->chunkData(i);
|
||||
else
|
||||
debug("RIFF::WAV::Properties::read() - Duplicate 'fmt ' chunk found.");
|
||||
}
|
||||
else if(name == "data") {
|
||||
if(streamLength == 0)
|
||||
else if (name == "data") {
|
||||
if (streamLength == 0)
|
||||
streamLength = file->chunkDataSize(i) + file->chunkPadding(i);
|
||||
else
|
||||
debug("RIFF::WAV::Properties::read() - Duplicate 'data' chunk found.");
|
||||
}
|
||||
else if(name == "fact") {
|
||||
if(totalSamples == 0)
|
||||
else if (name == "fact") {
|
||||
if (totalSamples == 0)
|
||||
totalSamples = file->chunkData(i).toUInt(0, false);
|
||||
else
|
||||
debug("RIFF::WAV::Properties::read() - Duplicate 'fact' chunk found.");
|
||||
}
|
||||
}
|
||||
|
||||
if(data.size() < 16) {
|
||||
if (data.size() < 16) {
|
||||
debug("RIFF::WAV::Properties::read() - 'fmt ' chunk not found or too short.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(streamLength == 0) {
|
||||
if (streamLength == 0) {
|
||||
debug("RIFF::WAV::Properties::read() - 'data' chunk not found.");
|
||||
return;
|
||||
}
|
||||
|
||||
d->format = data.toShort(0, false);
|
||||
if(d->format != FORMAT_PCM && totalSamples == 0) {
|
||||
if (d->format != FORMAT_PCM && totalSamples == 0) {
|
||||
debug("RIFF::WAV::Properties::read() - Non-PCM format, but 'fact' chunk not found.");
|
||||
return;
|
||||
}
|
||||
|
||||
d->channels = data.toShort(2, false);
|
||||
d->sampleRate = data.toUInt(4, false);
|
||||
d->channels = data.toShort(2, false);
|
||||
d->sampleRate = data.toUInt(4, false);
|
||||
d->bitsPerSample = data.toShort(14, false);
|
||||
|
||||
if(d->format != FORMAT_PCM)
|
||||
if (d->format != FORMAT_PCM)
|
||||
d->sampleFrames = totalSamples;
|
||||
else if(d->channels > 0 && d->bitsPerSample > 0)
|
||||
else if (d->channels > 0 && d->bitsPerSample > 0)
|
||||
d->sampleFrames = streamLength / (d->channels * ((d->bitsPerSample + 7) / 8));
|
||||
|
||||
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);
|
||||
d->length = static_cast<int>(length + 0.5);
|
||||
d->bitrate = static_cast<int>(streamLength * 8.0 / length + 0.5);
|
||||
}
|
||||
else {
|
||||
const unsigned int byteRate = data.toUInt(8, false);
|
||||
if(byteRate > 0) {
|
||||
d->length = static_cast<int>(streamLength * 1000.0 / byteRate + 0.5);
|
||||
if (byteRate > 0) {
|
||||
d->length = static_cast<int>(streamLength * 1000.0 / byteRate + 0.5);
|
||||
d->bitrate = static_cast<int>(byteRate * 8.0 / 1000.0 + 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
99
3rdparty/taglib/riff/wav/wavproperties.h
vendored
99
3rdparty/taglib/riff/wav/wavproperties.h
vendored
@@ -32,52 +32,51 @@
|
||||
namespace Strawberry_TagLib {
|
||||
namespace TagLib {
|
||||
|
||||
class ByteVector;
|
||||
class ByteVector;
|
||||
|
||||
namespace RIFF {
|
||||
namespace RIFF {
|
||||
|
||||
namespace WAV {
|
||||
namespace WAV {
|
||||
|
||||
class File;
|
||||
class File;
|
||||
|
||||
//! An implementation of audio property reading for WAV
|
||||
//! An implementation of audio property reading for WAV
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* This reads the data from an WAV stream found in the AudioProperties
|
||||
* API.
|
||||
*/
|
||||
|
||||
class TAGLIB_EXPORT Properties : public AudioProperties
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
class TAGLIB_EXPORT Properties : public AudioProperties {
|
||||
public:
|
||||
/*!
|
||||
* Create an instance of WAV::Properties with the data read from the
|
||||
* ByteVector \a data.
|
||||
*
|
||||
* \deprecated
|
||||
*/
|
||||
TAGLIB_DEPRECATED Properties(const ByteVector &data, ReadStyle style);
|
||||
TAGLIB_DEPRECATED Properties(const ByteVector &data, ReadStyle style);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Create an instance of WAV::Properties with the data read from the
|
||||
* ByteVector \a data and the length calculated using \a streamLength.
|
||||
*
|
||||
* \deprecated
|
||||
*/
|
||||
TAGLIB_DEPRECATED Properties(const ByteVector &data, unsigned int streamLength, ReadStyle style);
|
||||
TAGLIB_DEPRECATED Properties(const ByteVector &data, unsigned int streamLength, ReadStyle style);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Create an instance of WAV::Properties with the data read from the
|
||||
* WAV::File \a file.
|
||||
*/
|
||||
Properties(File *file, ReadStyle style);
|
||||
Properties(File *file, ReadStyle style);
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Destroys this WAV::Properties instance.
|
||||
*/
|
||||
virtual ~Properties();
|
||||
virtual ~Properties();
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns the length of the file in seconds. The length is rounded down to
|
||||
* the nearest whole second.
|
||||
*
|
||||
@@ -85,60 +84,60 @@ 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 number of bits per audio sample.
|
||||
*/
|
||||
int bitsPerSample() const;
|
||||
int bitsPerSample() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns the number of bits per audio sample.
|
||||
*
|
||||
* \note This method is just an alias of bitsPerSample().
|
||||
*
|
||||
* \deprecated
|
||||
*/
|
||||
TAGLIB_DEPRECATED int sampleWidth() const;
|
||||
TAGLIB_DEPRECATED int sampleWidth() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns the number of sample frames.
|
||||
*/
|
||||
unsigned int sampleFrames() const;
|
||||
unsigned int sampleFrames() const;
|
||||
|
||||
/*!
|
||||
/*!
|
||||
* Returns the format ID of the file.
|
||||
* 0 for unknown, 1 for PCM, 2 for ADPCM, 3 for 32/64-bit IEEE754, and
|
||||
* so forth.
|
||||
@@ -146,20 +145,20 @@ namespace TagLib {
|
||||
* \note For further information, refer to the WAVE Form Registration
|
||||
* Numbers in RFC 2361.
|
||||
*/
|
||||
int format() const;
|
||||
int format() const;
|
||||
|
||||
private:
|
||||
Properties(const Properties &);
|
||||
Properties &operator=(const Properties &);
|
||||
private:
|
||||
Properties(const Properties &);
|
||||
Properties &operator=(const Properties &);
|
||||
|
||||
void read(File *file);
|
||||
void read(File *file);
|
||||
|
||||
class PropertiesPrivate;
|
||||
PropertiesPrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
class PropertiesPrivate;
|
||||
PropertiesPrivate *d;
|
||||
};
|
||||
} // namespace WAV
|
||||
} // namespace RIFF
|
||||
} // namespace TagLib
|
||||
} // namespace Strawberry_TagLib
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user