diff options
Diffstat (limited to 'src/metadata/trueaudio')
-rw-r--r-- | src/metadata/trueaudio/Makefile.am | 16 | ||||
-rw-r--r-- | src/metadata/trueaudio/combinedtag.h | 171 | ||||
-rw-r--r-- | src/metadata/trueaudio/taglib_trueaudiofiletyperesolver.cpp | 44 | ||||
-rw-r--r-- | src/metadata/trueaudio/taglib_trueaudiofiletyperesolver.h | 36 | ||||
-rw-r--r-- | src/metadata/trueaudio/ttafile.cpp | 307 | ||||
-rw-r--r-- | src/metadata/trueaudio/ttafile.h | 178 | ||||
-rw-r--r-- | src/metadata/trueaudio/ttaproperties.cpp | 134 | ||||
-rw-r--r-- | src/metadata/trueaudio/ttaproperties.h | 86 |
8 files changed, 972 insertions, 0 deletions
diff --git a/src/metadata/trueaudio/Makefile.am b/src/metadata/trueaudio/Makefile.am new file mode 100644 index 0000000..01af09f --- /dev/null +++ b/src/metadata/trueaudio/Makefile.am @@ -0,0 +1,16 @@ +SUBDIRS = + +INCLUDES = $(all_includes) $(taglib_includes) +METASOURCES = AUTO +libtagtrueaudio_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libtagtrueaudio.la + +libtagtrueaudio_la_SOURCES = \ + ttafile.cpp \ + ttaproperties.cpp \ + taglib_trueaudiofiletyperesolver.cpp + +noinst_HEADERS = ttafile.h \ + ttaproperties.h \ + taglib_trueaudiofiletyperesolver.h + diff --git a/src/metadata/trueaudio/combinedtag.h b/src/metadata/trueaudio/combinedtag.h new file mode 100644 index 0000000..7d530d2 --- /dev/null +++ b/src/metadata/trueaudio/combinedtag.h @@ -0,0 +1,171 @@ +/*************************************************************************** + copyright : (C) 2004 by Allan Sandfeld Jensen + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef DO_NOT_DOCUMENT // Tell Doxygen not to document this header + +#ifndef TAGLIB_COMBINEDTAG_H +#define TAGLIB_COMBINEDTAG_H + +//////////////////////////////////////////////////////////////////////////////// +// Note that this header is not installed. +//////////////////////////////////////////////////////////////////////////////// + +#include <tag.h> + +namespace TagLib { + + /*! + * A union of two TagLib::Tags. + */ + class CombinedTag : public TagLib::Tag + { + public: + CombinedTag(Tag *tag1 = 0, Tag *tag2 = 0) + : TagLib::Tag(), + tag1(tag1), tag2(tag2) {} + + virtual String title() const { + if(tag1 && !tag1->title().isEmpty()) + return tag1->title(); + + if(tag2) + return tag2->title(); + + return String::null; + } + + virtual String artist() const { + if(tag1 && !tag1->artist().isEmpty()) + return tag1->artist(); + + if(tag2) + return tag2->artist(); + + return String::null; + } + + virtual String album() const { + if(tag1 && !tag1->album().isEmpty()) + return tag1->album(); + + if(tag2) + return tag2->album(); + + return String::null; + } + + virtual String comment() const { + if(tag1 && !tag1->comment().isEmpty()) + return tag1->comment(); + + if(tag2) + return tag2->comment(); + + return String::null; + } + + virtual String genre() const { + if(tag1 && !tag1->genre().isEmpty()) + return tag1->genre(); + + if(tag2) + return tag2->genre(); + + return String::null; + } + + virtual uint year() const { + if(tag1 && tag1->year() > 0) + return tag1->year(); + + if(tag2) + return tag2->year(); + + return 0; + } + + virtual uint track() const { + if(tag1 && tag1->track() > 0) + return tag1->track(); + + if(tag2) + return tag2->track(); + + return 0; + } + + virtual void setTitle(const String &s) { + if(tag1) + tag1->setTitle(s); + if(tag2) + tag2->setTitle(s); + } + + virtual void setArtist(const String &s) { + if(tag1) + tag1->setArtist(s); + if(tag2) + tag2->setArtist(s); + } + + virtual void setAlbum(const String &s) { + if(tag1) + tag1->setAlbum(s); + if(tag2) + tag2->setAlbum(s); + } + + virtual void setComment(const String &s) { + if(tag1) + tag1->setComment(s); + if(tag2) + tag2->setComment(s); + } + + virtual void setGenre(const String &s) { + if(tag1) + tag1->setGenre(s); + if(tag2) + tag2->setGenre(s); + } + + virtual void setYear(uint i) { + if(tag1) + tag1->setYear(i); + if(tag2) + tag2->setYear(i); + } + + virtual void setTrack(uint i) { + if(tag1) + tag1->setTrack(i); + if(tag2) + tag2->setTrack(i); + } + + private: + Tag *tag1; + Tag *tag2; + }; +} + +#endif +#endif diff --git a/src/metadata/trueaudio/taglib_trueaudiofiletyperesolver.cpp b/src/metadata/trueaudio/taglib_trueaudiofiletyperesolver.cpp new file mode 100644 index 0000000..e84e501 --- /dev/null +++ b/src/metadata/trueaudio/taglib_trueaudiofiletyperesolver.cpp @@ -0,0 +1,44 @@ +/*************************************************************************** + copyright : (C) 2006 by Martin Aumueller + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#include "taglib_trueaudiofiletyperesolver.h" +#include "ttafile.h" + +#include <string.h> + +TagLib::File *TTAFileTypeResolver::createFile(const char *fileName, + bool readProperties, + TagLib::AudioProperties::ReadStyle propertiesStyle) const +{ + const char *ext = strrchr(fileName, '.'); + if(ext && !strcasecmp(ext, ".tta")) + { + TagLib::TTA::File *f = new TagLib::TTA::File(fileName, readProperties, propertiesStyle); + if(f->isValid()) + return f; + else + { + delete f; + } + } + + return 0; +} diff --git a/src/metadata/trueaudio/taglib_trueaudiofiletyperesolver.h b/src/metadata/trueaudio/taglib_trueaudiofiletyperesolver.h new file mode 100644 index 0000000..e436e43 --- /dev/null +++ b/src/metadata/trueaudio/taglib_trueaudiofiletyperesolver.h @@ -0,0 +1,36 @@ +/*************************************************************************** + copyright : (C) 2006 by Martin Aumueller + email : [email protected] + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef TAGLIB_TRUEAUDIOFILETYPERESOLVER_H +#define TAGLIB_TRUEAUDIOFILETYPERESOLVER_H + +#include <taglib/tfile.h> +#include <taglib/fileref.h> + + +class TTAFileTypeResolver : public TagLib::FileRef::FileTypeResolver +{ + TagLib::File *createFile(const char *fileName, + bool readAudioProperties, + TagLib::AudioProperties::ReadStyle audioPropertiesStyle) const; +}; + +#endif diff --git a/src/metadata/trueaudio/ttafile.cpp b/src/metadata/trueaudio/ttafile.cpp new file mode 100644 index 0000000..3a02e20 --- /dev/null +++ b/src/metadata/trueaudio/ttafile.cpp @@ -0,0 +1,307 @@ +/*************************************************************************** + copyright : (C) 2006 by Lukáš Lalinský + email : [email protected] + + copyright : (C) 2004 by Allan Sandfeld Jensen + email : [email protected] + (original MPC implementation) + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#include <tbytevector.h> +#include <tstring.h> +#if 0 +#include <tdebug.h> +#endif + +#include "ttafile.h" +#include "id3v1tag.h" +#include "id3v2tag.h" +#include "id3v2header.h" +#include "combinedtag.h" + +using namespace TagLib; + +class TTA::File::FilePrivate +{ +public: + FilePrivate(const ID3v2::FrameFactory *frameFactory = ID3v2::FrameFactory::instance()) : + ID3v2FrameFactory(frameFactory), + ID3v2Tag(0), + ID3v2Location(-1), + ID3v2OriginalSize(0), + ID3v1Tag(0), + ID3v1Location(-1), + tag(0), + properties(0), + scanned(false), + hasID3v1(false), + hasID3v2(false) {} + + ~FilePrivate() + { + if (tag != ID3v1Tag && tag != ID3v2Tag) delete tag; + delete ID3v1Tag; + delete ID3v2Tag; + delete properties; + } + + const ID3v2::FrameFactory *ID3v2FrameFactory; + ID3v2::Tag *ID3v2Tag; + long ID3v2Location; + uint ID3v2OriginalSize; + + ID3v1::Tag *ID3v1Tag; + long ID3v1Location; + + Tag *tag; + + Properties *properties; + bool scanned; + + // These indicate whether the file *on disk* has these tags, not if + // this data structure does. This is used in computing offsets. + + bool hasID3v1; + bool hasID3v2; +}; + +//////////////////////////////////////////////////////////////////////////////// +// public members +//////////////////////////////////////////////////////////////////////////////// + +TTA::File::File(const char *file, bool readProperties, + Properties::ReadStyle propertiesStyle) : TagLib::File(file) +{ + d = new FilePrivate; + if(isOpen()) + read(readProperties, propertiesStyle); +} + +TTA::File::File(const char *file, ID3v2::FrameFactory *frameFactory, + bool readProperties, Properties::ReadStyle propertiesStyle) : + TagLib::File(file) +{ + d = new FilePrivate(frameFactory); + if(isOpen()) + read(readProperties, propertiesStyle); +} + +TTA::File::~File() +{ + delete d; +} + +TagLib::Tag *TTA::File::tag() const +{ + return d->tag; +} + +TTA::Properties *TTA::File::audioProperties() const +{ + return d->properties; +} + +void TTA::File::setID3v2FrameFactory(const ID3v2::FrameFactory *factory) +{ + d->ID3v2FrameFactory = factory; +} + +bool TTA::File::save() +{ + if(readOnly()) { +#if 0 + debug("TTA::File::save() -- File is read only."); +#endif + return false; + } + + // Update ID3v2 tag + + if(d->ID3v2Tag) { + if(!d->hasID3v2) { + d->ID3v2Location = 0; + d->ID3v2OriginalSize = 0; + } + insert(d->ID3v2Tag->render(), d->ID3v2Location, d->ID3v2OriginalSize); + d->hasID3v2 = true; + } + else if(d->hasID3v2) { + removeBlock(d->ID3v2Location, d->ID3v2OriginalSize); + d->hasID3v2 = false; + } + + // Update ID3v1 tag + + if(d->ID3v1Tag) { + if(!d->hasID3v1) { + seek(0, End); + d->ID3v1Location = tell(); + } + else + seek(d->ID3v1Location); + writeBlock(d->ID3v1Tag->render()); + d->hasID3v1 = true; + } + else if(d->hasID3v1) { + removeBlock(d->ID3v1Location, 128); + d->hasID3v1 = false; + } + + return true; +} + +ID3v1::Tag *TTA::File::ID3v1Tag(bool create) +{ + if(!create || d->ID3v1Tag) + return d->ID3v1Tag; + + // no ID3v1 tag exists and we've been asked to create one + + d->ID3v1Tag = new ID3v1::Tag; + + if(d->ID3v2Tag) + d->tag = new CombinedTag(d->ID3v2Tag, d->ID3v1Tag); + else + d->tag = d->ID3v1Tag; + + return d->ID3v1Tag; +} + +ID3v2::Tag *TTA::File::ID3v2Tag(bool create) +{ + if(!create || d->ID3v2Tag) + return d->ID3v2Tag; + + // no ID3v2 tag exists and we've been asked to create one + + d->ID3v2Tag = new ID3v2::Tag; + + if(d->ID3v1Tag) + d->tag = new CombinedTag(d->ID3v2Tag, d->ID3v1Tag); + else + d->tag = d->ID3v2Tag; + + return d->ID3v2Tag; +} + +void TTA::File::remove(int tags) +{ + if(tags & ID3v1) { + delete d->ID3v1Tag; + d->ID3v1Tag = 0; + + if(d->ID3v2Tag) + d->tag = d->ID3v2Tag; + else + d->tag = d->ID3v2Tag = new ID3v2::Tag; + } + + if(tags & ID3v2) { + delete d->ID3v2Tag; + d->ID3v2Tag = 0; + + if(d->ID3v1Tag) + d->tag = d->ID3v1Tag; + else + d->tag = d->ID3v2Tag = new ID3v2::Tag; + } +} + + +//////////////////////////////////////////////////////////////////////////////// +// private members +//////////////////////////////////////////////////////////////////////////////// + +void TTA::File::read(bool readProperties, Properties::ReadStyle /* propertiesStyle */) +{ + // Look for an ID3v2 tag + + d->ID3v2Location = findID3v2(); + + if(d->ID3v2Location >= 0) { + + d->ID3v2Tag = new ID3v2::Tag(this, d->ID3v2Location, d->ID3v2FrameFactory); + + d->ID3v2OriginalSize = d->ID3v2Tag->header()->completeTagSize(); + + if(d->ID3v2Tag->header()->tagSize() <= 0) { + delete d->ID3v2Tag; + d->ID3v2Tag = 0; + } + else + d->hasID3v2 = true; + } + + // Look for an ID3v1 tag + + d->ID3v1Location = findID3v1(); + + if(d->ID3v1Location >= 0) { + d->ID3v1Tag = new ID3v1::Tag(this, d->ID3v1Location); + d->hasID3v1 = true; + } + + if(d->hasID3v1 && d->hasID3v2) + d->tag = new CombinedTag(d->ID3v2Tag, d->ID3v1Tag); + else { + if(d->hasID3v1) + d->tag = d->ID3v1Tag; + else { + if(d->hasID3v2) + d->tag = d->ID3v2Tag; + else + d->tag = d->ID3v2Tag = new ID3v2::Tag; + } + } + + // Look for TTA metadata + + if(readProperties) { + seek(d->ID3v2Location + d->ID3v2OriginalSize); + d->properties = new Properties(readBlock(TTA::HeaderSize), + length() - d->ID3v2OriginalSize); + } +} + +long TTA::File::findID3v1() +{ + if(!isValid()) + return -1; + + seek(-128, End); + long p = tell(); + + if(readBlock(3) == ID3v1::Tag::fileIdentifier()) + return p; + + return -1; +} + +long TTA::File::findID3v2() +{ + if(!isValid()) + return -1; + + seek(0); + + if(readBlock(3) == ID3v2::Header::fileIdentifier()) + return 0; + + return -1; +} diff --git a/src/metadata/trueaudio/ttafile.h b/src/metadata/trueaudio/ttafile.h new file mode 100644 index 0000000..2cb0785 --- /dev/null +++ b/src/metadata/trueaudio/ttafile.h @@ -0,0 +1,178 @@ +/*************************************************************************** + copyright : (C) 2006 by Lukáš Lalinský + email : [email protected] + + copyright : (C) 2004 by Allan Sandfeld Jensen + email : [email protected] + (original MPC implementation) + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef TAGLIB_TTAFILE_H +#define TAGLIB_TTAFILE_H + +#include "tfile.h" + +#include "ttaproperties.h" + +namespace TagLib { + + class Tag; + + namespace ID3v2 { class Tag; class FrameFactory; } + namespace ID3v1 { class Tag; } + + //! An implementation of TTA metadata + + /*! + * This is implementation of TTA metadata. + * + * This supports ID3v1 and ID3v2 tags as well as reading stream + * properties from the file. + */ + + namespace TTA { + + //! An implementation of TagLib::File with TTA specific methods + + /*! + * This implements and provides an interface for TTA 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 TTA files. + */ + + class File : public TagLib::File + { + public: + /*! + * This set of flags is used for various operations and is suitable for + * being OR-ed together. + */ + enum TagTypes { + //! Empty set. Matches no tag types. + NoTags = 0x0000, + //! Matches ID3v1 tags. + ID3v1 = 0x0001, + //! Matches ID3v2 tags. + ID3v2 = 0x0002, + //! Matches all tag types. + AllTags = 0xffff + }; + + /*! + * Contructs an MPC 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(const char *file, bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Contructs an MPC 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. The frames will be created using + * \a frameFactory. + */ + File(const char *file, ID3v2::FrameFactory *frameFactory, + bool readProperties = true, + Properties::ReadStyle propertiesStyle = Properties::Average); + + /*! + * Destroys this instance of the File. + */ + virtual ~File(); + + /*! + * Returns the Tag for this file. This will be an APE tag, an ID3v1 tag + * or a combination of the two. + */ + virtual TagLib::Tag *tag() const; + + /*! + * Returns the MPC::Properties for this file. If no audio properties + * were read then this will return a null pointer. + */ + virtual Properties *audioProperties() const; + + /*! + * Set the ID3v2::FrameFactory to something other than the default. + * + * \see ID3v2FrameFactory + */ + void setID3v2FrameFactory(const ID3v2::FrameFactory *factory); + + /*! + * Saves the file. + */ + virtual bool save(); + + /*! + * Returns a pointer to the ID3v2 tag of the file. + * + * If \a create is false (the default) this will return a null pointer + * if there is no valid ID3v2 tag. If \a create is true it will create + * an ID3v1 tag if one does not exist. If there is already an APE tag, the + * new ID3v1 tag will be placed after it. + * + * \note The Tag <b>is still</b> owned by the TTA::File and should not be + * deleted by the user. It will be deleted when the file (object) is + * destroyed. + */ + ID3v1::Tag *ID3v1Tag(bool create = false); + + /*! + * Returns a pointer to the ID3v1 tag of the file. + * + * If \a create is false (the default) this will return a null pointer + * if there is no valid ID3v1 tag. If \a create is true it will create + * an ID3v1 tag if one does not exist. If there is already an APE tag, the + * new ID3v1 tag will be placed after it. + * + * \note The Tag <b>is still</b> owned by the TTA::File and should not be + * deleted by the user. It will be deleted when the file (object) is + * destroyed. + */ + ID3v2::Tag *ID3v2Tag(bool create = false); + + /*! + * This will remove the tags that match the OR-ed together TagTypes from the + * file. By default it removes all tags. + * + * \note This will also invalidate pointers to the tags + * as their memory will be freed. + * \note In order to make the removal permanent save() still needs to be called + */ + void remove(int tags = AllTags); + + private: + File(const File &); + File &operator=(const File &); + + void read(bool readProperties, Properties::ReadStyle propertiesStyle); + void scan(); + long findID3v1(); + long findID3v2(); + + class FilePrivate; + FilePrivate *d; + }; + } +} + +#endif diff --git a/src/metadata/trueaudio/ttaproperties.cpp b/src/metadata/trueaudio/ttaproperties.cpp new file mode 100644 index 0000000..c4f6a29 --- /dev/null +++ b/src/metadata/trueaudio/ttaproperties.cpp @@ -0,0 +1,134 @@ +/*************************************************************************** + copyright : (C) 2006 by Lukáš Lalinský + email : [email protected] + + copyright : (C) 2004 by Allan Sandfeld Jensen + email : [email protected] + (original MPC implementation) + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#include <tstring.h> +#if 0 +#include <tdebug.h> +#endif +#include <bitset> + +#include "ttaproperties.h" +#include "ttafile.h" + +using namespace TagLib; + +class TTA::Properties::PropertiesPrivate +{ +public: + PropertiesPrivate(const ByteVector &d, long length, ReadStyle s) : + data(d), + streamLength(length), + style(s), + version(0), + length(0), + bitrate(0), + sampleRate(0), + channels(0), + bitsPerSample(0) {} + + ByteVector data; + long streamLength; + ReadStyle style; + int version; + int length; + int bitrate; + int sampleRate; + int channels; + int bitsPerSample; +}; + +//////////////////////////////////////////////////////////////////////////////// +// public members +//////////////////////////////////////////////////////////////////////////////// + +TTA::Properties::Properties(const ByteVector &data, long streamLength, ReadStyle style) : AudioProperties(style) +{ + d = new PropertiesPrivate(data, streamLength, style); + read(); +} + +TTA::Properties::~Properties() +{ + delete d; +} + +int TTA::Properties::length() const +{ + return d->length; +} + +int TTA::Properties::bitrate() const +{ + return d->bitrate; +} + +int TTA::Properties::sampleRate() const +{ + return d->sampleRate; +} + +int TTA::Properties::bitsPerSample() const +{ + return d->bitsPerSample; +} + +int TTA::Properties::channels() const +{ + return d->channels; +} + +int TTA::Properties::ttaVersion() const +{ + return d->version; +} + +//////////////////////////////////////////////////////////////////////////////// +// private members +//////////////////////////////////////////////////////////////////////////////// + +void TTA::Properties::read() +{ + if(!d->data.startsWith("TTA")) + return; + + int pos = 3; + + d->version = d->data[pos] - '0'; + pos += 1 + 2; + + d->channels = d->data.mid(pos, 2).toShort(false); + pos += 2; + + d->bitsPerSample = d->data.mid(pos, 2).toShort(false); + pos += 2; + + d->sampleRate = d->data.mid(pos, 4).toUInt(false); + pos += 4; + + unsigned long samples = d->data.mid(pos, 4).toUInt(false); + d->length = samples / d->sampleRate; + + d->bitrate = d->length > 0 ? ((d->streamLength * 8L) / d->length) / 1000 : 0; +} diff --git a/src/metadata/trueaudio/ttaproperties.h b/src/metadata/trueaudio/ttaproperties.h new file mode 100644 index 0000000..e694e3d --- /dev/null +++ b/src/metadata/trueaudio/ttaproperties.h @@ -0,0 +1,86 @@ +/*************************************************************************** + copyright : (C) 2006 by Lukáš Lalinský + email : [email protected] + + copyright : (C) 2004 by Allan Sandfeld Jensen + email : [email protected] + (original MPC implementation) + ***************************************************************************/ + +/*************************************************************************** + * This library is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Lesser General Public License version * + * 2.1 as published by the Free Software Foundation. * + * * + * This library is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with this library; if not, write to the Free Software * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * + * MA 02110-1301 USA * + ***************************************************************************/ + +#ifndef TAGLIB_TTAPROPERTIES_H +#define TAGLIB_TTAPROPERTIES_H + +#include "audioproperties.h" + +namespace TagLib { + + namespace TTA { + + class File; + + static const uint HeaderSize = 18; + + //! An implementation of audio property reading for TTA + + /*! + * This reads the data from an TTA stream found in the AudioProperties + * API. + */ + + class Properties : public AudioProperties + { + public: + /*! + * Create an instance of TTA::Properties with the data read from the + * ByteVector \a data. + */ + Properties(const ByteVector &data, long streamLength, ReadStyle style = Average); + + /*! + * Destroys this TTA::Properties instance. + */ + virtual ~Properties(); + + // Reimplementations. + + virtual int length() const; + virtual int bitrate() const; + virtual int sampleRate() const; + virtual int channels() const; + + /*! + * Returns number of bits per sample. + */ + int bitsPerSample() const; + + /*! + * Returns the major version number. + */ + int ttaVersion() const; + + private: + void read(); + + class PropertiesPrivate; + PropertiesPrivate *d; + }; + } +} + +#endif |