Format taglib sources

This commit is contained in:
Jonas Kvinge
2020-06-13 19:02:42 +02:00
parent 72bff7fa35
commit 4ce099294c
224 changed files with 12905 additions and 15623 deletions

View File

@@ -36,19 +36,15 @@ using namespace Strawberry_TagLib::TagLib;
// The DSF specification is located at http://dsd-guide.com/sites/default/files/white-papers/DSFFileFormatSpec_E.pdf
class DSF::File::FilePrivate
{
public:
FilePrivate() :
fileSize(0),
metadataOffset(0),
properties(nullptr),
tag(nullptr)
{
class DSF::File::FilePrivate {
public:
FilePrivate() : fileSize(0),
metadataOffset(0),
properties(nullptr),
tag(nullptr) {
}
~FilePrivate()
{
~FilePrivate() {
delete properties;
delete tag;
}
@@ -63,11 +59,10 @@ public:
// static members
////////////////////////////////////////////////////////////////////////////////
bool DSF::File::isSupported(IOStream *stream)
{
// A DSF file has to start with "DSD "
const ByteVector id = Utils::readHeader(stream, 4, false);
return id.startsWith("DSD ");
bool DSF::File::isSupported(IOStream *stream) {
// A DSF file has to start with "DSD "
const ByteVector id = Utils::readHeader(stream, 4, false);
return id.startsWith("DSD ");
}
////////////////////////////////////////////////////////////////////////////////
@@ -75,73 +70,63 @@ bool DSF::File::isSupported(IOStream *stream)
////////////////////////////////////////////////////////////////////////////////
DSF::File::File(FileName file, bool readProperties,
Properties::ReadStyle propertiesStyle) :
Strawberry_TagLib::TagLib::File(file),
d(new FilePrivate())
{
if(isOpen())
Properties::ReadStyle propertiesStyle) : Strawberry_TagLib::TagLib::File(file),
d(new FilePrivate()) {
if (isOpen())
read(readProperties, propertiesStyle);
}
DSF::File::File(IOStream *stream, bool readProperties,
Properties::ReadStyle propertiesStyle) :
Strawberry_TagLib::TagLib::File(stream),
d(new FilePrivate())
{
if(isOpen())
Properties::ReadStyle propertiesStyle) : Strawberry_TagLib::TagLib::File(stream),
d(new FilePrivate()) {
if (isOpen())
read(readProperties, propertiesStyle);
}
DSF::File::~File()
{
DSF::File::~File() {
delete d;
}
ID3v2::Tag *DSF::File::tag() const
{
ID3v2::Tag *DSF::File::tag() const {
return d->tag;
}
PropertyMap DSF::File::properties() const
{
PropertyMap DSF::File::properties() const {
return d->tag->properties();
}
PropertyMap DSF::File::setProperties(const PropertyMap &properties)
{
PropertyMap DSF::File::setProperties(const PropertyMap &properties) {
return d->tag->setProperties(properties);
}
DSF::Properties *DSF::File::audioProperties() const
{
DSF::Properties *DSF::File::audioProperties() const {
return d->properties;
}
bool DSF::File::save()
{
if(readOnly()) {
bool DSF::File::save() {
if (readOnly()) {
debug("DSF::File::save() -- File is read only.");
return false;
}
if(!isValid()) {
if (!isValid()) {
debug("DSF::File::save() -- Trying to save invalid file.");
return false;
}
// Three things must be updated: the file size, the tag data, and the metadata offset
if(d->tag->isEmpty()) {
if (d->tag->isEmpty()) {
long long newFileSize = d->metadataOffset ? d->metadataOffset : d->fileSize;
// Update the file size
if(d->fileSize != newFileSize) {
if (d->fileSize != newFileSize) {
insert(ByteVector::fromLongLong(newFileSize, false), 12, 8);
d->fileSize = newFileSize;
}
// Update the metadata offset to 0 since there is no longer a tag
if(d->metadataOffset) {
if (d->metadataOffset) {
insert(ByteVector::fromLongLong(0ULL, false), 20, 8);
d->metadataOffset = 0;
}
@@ -157,13 +142,13 @@ bool DSF::File::save()
long long oldTagSize = d->fileSize - newMetadataOffset;
// Update the file size
if(d->fileSize != newFileSize) {
if (d->fileSize != newFileSize) {
insert(ByteVector::fromLongLong(newFileSize, false), 12, 8);
d->fileSize = newFileSize;
}
// Update the metadata offset
if(d->metadataOffset != newMetadataOffset) {
if (d->metadataOffset != newMetadataOffset) {
insert(ByteVector::fromLongLong(newMetadataOffset, false), 20, 8);
d->metadataOffset = newMetadataOffset;
}
@@ -180,14 +165,13 @@ bool DSF::File::save()
////////////////////////////////////////////////////////////////////////////////
void DSF::File::read(bool, Properties::ReadStyle propertiesStyle)
{
void DSF::File::read(bool, Properties::ReadStyle propertiesStyle) {
// A DSF file consists of four chunks: DSD chunk, format chunk, data chunk, and metadata chunk
// The file format is not chunked in the sense of a RIFF File, though
// DSD chunk
ByteVector chunkName = readBlock(4);
if(chunkName != "DSD ") {
if (chunkName != "DSD ") {
debug("DSF::File::read() -- Not a DSF file.");
setValid(false);
return;
@@ -196,7 +180,7 @@ void DSF::File::read(bool, Properties::ReadStyle propertiesStyle)
long long chunkSize = readBlock(8).toLongLong(false);
// Integrity check
if(28 != chunkSize) {
if (28 != chunkSize) {
debug("DSF::File::read() -- File is corrupted, wrong chunk size");
setValid(false);
return;
@@ -205,7 +189,7 @@ void DSF::File::read(bool, Properties::ReadStyle propertiesStyle)
d->fileSize = readBlock(8).toLongLong(false);
// File is malformed or corrupted
if(d->fileSize != length()) {
if (d->fileSize != length()) {
debug("DSF::File::read() -- File is corrupted wrong length");
setValid(false);
return;
@@ -214,7 +198,7 @@ void DSF::File::read(bool, Properties::ReadStyle propertiesStyle)
d->metadataOffset = readBlock(8).toLongLong(false);
// File is malformed or corrupted
if(d->metadataOffset > d->fileSize) {
if (d->metadataOffset > d->fileSize) {
debug("DSF::File::read() -- Invalid metadata offset.");
setValid(false);
return;
@@ -222,7 +206,7 @@ void DSF::File::read(bool, Properties::ReadStyle propertiesStyle)
// Format chunk
chunkName = readBlock(4);
if(chunkName != "fmt ") {
if (chunkName != "fmt ") {
debug("DSF::File::read() -- Missing 'fmt ' chunk.");
setValid(false);
return;
@@ -235,9 +219,8 @@ void DSF::File::read(bool, Properties::ReadStyle propertiesStyle)
// Skip the data chunk
// A metadata offset of 0 indicates the absence of an ID3v2 tag
if(0 == d->metadataOffset)
if (0 == d->metadataOffset)
d->tag = new ID3v2::Tag();
else
d->tag = new ID3v2::Tag(this, d->metadataOffset);
}

View File

@@ -33,98 +33,96 @@
namespace Strawberry_TagLib {
namespace TagLib {
//! An implementation of DSF metadata
//! An implementation of DSF metadata
/*!
/*!
* This is implementation of DSF metadata.
*
* This supports an ID3v2 tag as well as properties from the file.
*/
namespace DSF {
namespace DSF {
//! An implementation of Strawberry_TagLib::TagLib::File with DSF specific methods
//! An implementation of Strawberry_TagLib::TagLib::File with DSF specific methods
/*!
/*!
* This implements and provides an interface for DSF files to the
* Strawberry_TagLib::TagLib::Tag and Strawberry_TagLib::TagLib::AudioProperties interfaces by way of implementing
* the abstract Strawberry_TagLib::TagLib::File API as well as providing some additional
* information specific to DSF files.
*/
class TAGLIB_EXPORT File : public Strawberry_TagLib::TagLib::File
{
public:
/*!
class TAGLIB_EXPORT File : public Strawberry_TagLib::TagLib::File {
public:
/*!
* Constructs an DSF file from \a file. If \a readProperties is true the
* file's audio properties will also be read using \a propertiesStyle. If
* false, \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 DSF file from \a file. If \a readProperties is true the
* file's audio properties will also be read using \a propertiesStyle. If
* false, \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.
*/
ID3v2::Tag *tag() const;
ID3v2::Tag *tag() const;
/*!
/*!
* Implements the unified property interface -- export function.
* This method forwards to ID3v2::Tag::properties().
*/
PropertyMap properties() const;
PropertyMap properties() const;
/*!
/*!
* Implements the unified property interface -- import function.
* This method forwards to ID3v2::Tag::setProperties().
*/
PropertyMap setProperties(const PropertyMap &);
PropertyMap setProperties(const PropertyMap &);
/*!
/*!
* Returns the DSF::AudioProperties 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();
/*!
/*!
* Returns whether or not the given \a stream can be opened as a DSF
* 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, Properties::ReadStyle propertiesStyle);
void read(bool readProperties, Properties::ReadStyle propertiesStyle);
class FilePrivate;
FilePrivate *d;
};
}
}
}
class FilePrivate;
FilePrivate *d;
};
} // namespace DSF
} // namespace TagLib
} // namespace Strawberry_TagLib
#endif

View File

@@ -30,21 +30,18 @@
using namespace Strawberry_TagLib::TagLib;
class DSF::Properties::PropertiesPrivate
{
public:
PropertiesPrivate() :
formatVersion(0),
formatID(0),
channelType(0),
channelNum(0),
samplingFrequency(0),
bitsPerSample(0),
sampleCount(0),
blockSizePerChannel(0),
bitrate(0),
length(0)
{
class DSF::Properties::PropertiesPrivate {
public:
PropertiesPrivate() : formatVersion(0),
formatID(0),
channelType(0),
channelNum(0),
samplingFrequency(0),
bitsPerSample(0),
sampleCount(0),
blockSizePerChannel(0),
bitrate(0),
length(0) {
}
// Nomenclature is from DSF file format specification
@@ -66,75 +63,61 @@ public:
// public members
////////////////////////////////////////////////////////////////////////////////
DSF::Properties::Properties(const ByteVector &data, ReadStyle style) : Strawberry_TagLib::TagLib::AudioProperties(style)
{
DSF::Properties::Properties(const ByteVector &data, ReadStyle style) : Strawberry_TagLib::TagLib::AudioProperties(style) {
d = new PropertiesPrivate;
read(data);
}
DSF::Properties::~Properties()
{
DSF::Properties::~Properties() {
delete d;
}
int DSF::Properties::length() const
{
int DSF::Properties::length() const {
return lengthInSeconds();
}
int DSF::Properties::lengthInSeconds() const
{
int DSF::Properties::lengthInSeconds() const {
return d->length / 1000;
}
int DSF::Properties::lengthInMilliseconds() const
{
int DSF::Properties::lengthInMilliseconds() const {
return d->length;
}
int DSF::Properties::bitrate() const
{
int DSF::Properties::bitrate() const {
return d->bitrate;
}
int DSF::Properties::sampleRate() const
{
int DSF::Properties::sampleRate() const {
return d->samplingFrequency;
}
int DSF::Properties::channels() const
{
int DSF::Properties::channels() const {
return d->channelNum;
}
// DSF specific
int DSF::Properties::formatVersion() const
{
int DSF::Properties::formatVersion() const {
return d->formatVersion;
}
int DSF::Properties::formatID() const
{
int DSF::Properties::formatID() const {
return d->formatID;
}
int DSF::Properties::channelType() const
{
int DSF::Properties::channelType() const {
return d->channelType;
}
int DSF::Properties::bitsPerSample() const
{
int DSF::Properties::bitsPerSample() const {
return d->bitsPerSample;
}
long long DSF::Properties::sampleCount() const
{
long long DSF::Properties::sampleCount() const {
return d->sampleCount;
}
int DSF::Properties::blockSizePerChannel() const
{
int DSF::Properties::blockSizePerChannel() const {
return d->blockSizePerChannel;
}
@@ -142,20 +125,16 @@ int DSF::Properties::blockSizePerChannel() const
// private members
////////////////////////////////////////////////////////////////////////////////
void DSF::Properties::read(const ByteVector &data)
{
d->formatVersion = data.toUInt(0U,false);
d->formatID = data.toUInt(4U,false);
d->channelType = data.toUInt(8U,false);
d->channelNum = data.toUInt(12U,false);
d->samplingFrequency = data.toUInt(16U,false);
d->bitsPerSample = data.toUInt(20U,false);
d->sampleCount = data.toLongLong(24U,false);
d->blockSizePerChannel = data.toUInt(32U,false);
void DSF::Properties::read(const ByteVector &data) {
d->formatVersion = data.toUInt(0U, false);
d->formatID = data.toUInt(4U, false);
d->channelType = data.toUInt(8U, false);
d->channelNum = data.toUInt(12U, false);
d->samplingFrequency = data.toUInt(16U, false);
d->bitsPerSample = data.toUInt(20U, false);
d->sampleCount = data.toLongLong(24U, false);
d->blockSizePerChannel = data.toUInt(32U, false);
d->bitrate
= static_cast<unsigned int>((d->samplingFrequency * d->bitsPerSample * d->channelNum) / 1000.0 + 0.5);
d->length
= d->samplingFrequency > 0 ? static_cast<unsigned int>(d->sampleCount * 1000.0 / d->samplingFrequency + 0.5) : 0;
d->bitrate = static_cast<unsigned int>((d->samplingFrequency * d->bitsPerSample * d->channelNum) / 1000.0 + 0.5);
d->length = d->samplingFrequency > 0 ? static_cast<unsigned int>(d->sampleCount * 1000.0 / d->samplingFrequency + 0.5) : 0;
}

View File

@@ -31,64 +31,62 @@
namespace Strawberry_TagLib {
namespace TagLib {
namespace DSF {
namespace DSF {
class File;
class File;
//! An implementation of audio property reading for DSF
//! An implementation of audio property reading for DSF
/*!
/*!
* This reads the data from a DSF stream found in the AudioProperties
* API.
*/
class TAGLIB_EXPORT Properties : public Strawberry_TagLib::TagLib::AudioProperties
{
public:
/*!
class TAGLIB_EXPORT Properties : public Strawberry_TagLib::TagLib::AudioProperties {
public:
/*!
* Create an instance of DSF::AudioProperties with the data read from the
* ByteVector \a data.
*/
Properties(const ByteVector &data, ReadStyle style);
Properties(const ByteVector &data, ReadStyle style);
/*!
/*!
* Destroys this DSF::AudioProperties instance.
*/
virtual ~Properties();
virtual ~Properties();
// Reimplementations.
// Reimplementations.
virtual int length() const;
virtual int lengthInSeconds() const;
virtual int lengthInMilliseconds() const;
virtual int bitrate() const;
virtual int sampleRate() const;
virtual int channels() const;
virtual int length() const;
virtual int lengthInSeconds() const;
virtual int lengthInMilliseconds() const;
virtual int bitrate() const;
virtual int sampleRate() const;
virtual int channels() const;
int formatVersion() const;
int formatID() const;
int formatVersion() const;
int formatID() const;
/*!
/*!
* Channel type values: 1 = mono, 2 = stereo, 3 = 3 channels,
* 4 = quad, 5 = 4 channels, 6 = 5 channels, 7 = 5.1 channels
*/
int channelType() const;
int bitsPerSample() const;
long long sampleCount() const;
int blockSizePerChannel() const;
int channelType() const;
int bitsPerSample() const;
long long sampleCount() const;
int blockSizePerChannel() const;
private:
Properties(const Properties &);
Properties &operator=(const Properties &);
private:
Properties(const Properties &);
Properties &operator=(const Properties &);
void read(const ByteVector &data);
void read(const ByteVector &data);
class PropertiesPrivate;
PropertiesPrivate *d;
};
}
}
}
class PropertiesPrivate;
PropertiesPrivate *d;
};
} // namespace DSF
} // namespace TagLib
} // namespace Strawberry_TagLib
#endif