diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-01 19:09:31 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-01 19:09:31 +0000 |
commit | f2cfda2a54780868dfe0af7bd652fcd4906547da (patch) | |
tree | c6ac23545528f5701818424f2af5f79ce3665e6c /src/metadata/wavpack | |
download | soundkonverter-f2cfda2a54780868dfe0af7bd652fcd4906547da.tar.gz soundkonverter-f2cfda2a54780868dfe0af7bd652fcd4906547da.zip |
Added KDE3 version of SoundKonverter
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/soundkonverter@1097614 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/metadata/wavpack')
-rw-r--r-- | src/metadata/wavpack/Makefile.am | 16 | ||||
-rw-r--r-- | src/metadata/wavpack/combinedtag.h | 171 | ||||
-rw-r--r-- | src/metadata/wavpack/taglib_wavpackfiletyperesolver.cpp | 44 | ||||
-rw-r--r-- | src/metadata/wavpack/taglib_wavpackfiletyperesolver.h | 36 | ||||
-rw-r--r-- | src/metadata/wavpack/wvfile.cpp | 311 | ||||
-rw-r--r-- | src/metadata/wavpack/wvfile.h | 160 | ||||
-rw-r--r-- | src/metadata/wavpack/wvproperties.cpp | 141 | ||||
-rw-r--r-- | src/metadata/wavpack/wvproperties.h | 86 |
8 files changed, 965 insertions, 0 deletions
diff --git a/src/metadata/wavpack/Makefile.am b/src/metadata/wavpack/Makefile.am new file mode 100644 index 0000000..93a98c6 --- /dev/null +++ b/src/metadata/wavpack/Makefile.am @@ -0,0 +1,16 @@ +SUBDIRS = + +INCLUDES = $(all_includes) $(taglib_includes) +METASOURCES = AUTO +libtagwavpack_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libtagwavpack.la + +libtagwavpack_la_SOURCES = \ + wvfile.cpp \ + wvproperties.cpp \ + taglib_wavpackfiletyperesolver.cpp + +noinst_HEADERS = wvfile.h \ + wvproperties.h \ + taglib_wavpackfiletyperesolver.h + diff --git a/src/metadata/wavpack/combinedtag.h b/src/metadata/wavpack/combinedtag.h new file mode 100644 index 0000000..7d530d2 --- /dev/null +++ b/src/metadata/wavpack/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/wavpack/taglib_wavpackfiletyperesolver.cpp b/src/metadata/wavpack/taglib_wavpackfiletyperesolver.cpp new file mode 100644 index 0000000..fe289a2 --- /dev/null +++ b/src/metadata/wavpack/taglib_wavpackfiletyperesolver.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_wavpackfiletyperesolver.h" +#include "wvfile.h" + +#include <string.h> + +TagLib::File *WavPackFileTypeResolver::createFile(const char *fileName, + bool readProperties, + TagLib::AudioProperties::ReadStyle propertiesStyle) const +{ + const char *ext = strrchr(fileName, '.'); + if(ext && !strcasecmp(ext, ".wv")) + { + TagLib::WavPack::File *f = new TagLib::WavPack::File(fileName, readProperties, propertiesStyle); + if(f->isValid()) + return f; + else + { + delete f; + } + } + + return 0; +} diff --git a/src/metadata/wavpack/taglib_wavpackfiletyperesolver.h b/src/metadata/wavpack/taglib_wavpackfiletyperesolver.h new file mode 100644 index 0000000..b9d4500 --- /dev/null +++ b/src/metadata/wavpack/taglib_wavpackfiletyperesolver.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_WAVPACKFILETYPERESOLVER_H +#define TAGLIB_WAVPACKFILETYPERESOLVER_H + +#include <taglib/tfile.h> +#include <taglib/fileref.h> + + +class WavPackFileTypeResolver : public TagLib::FileRef::FileTypeResolver +{ + TagLib::File *createFile(const char *fileName, + bool readAudioProperties, + TagLib::AudioProperties::ReadStyle audioPropertiesStyle) const; +}; + +#endif diff --git a/src/metadata/wavpack/wvfile.cpp b/src/metadata/wavpack/wvfile.cpp new file mode 100644 index 0000000..3890bc9 --- /dev/null +++ b/src/metadata/wavpack/wvfile.cpp @@ -0,0 +1,311 @@ +/*************************************************************************** + 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 "wvfile.h" +#include "id3v1tag.h" +#include "id3v2header.h" +#include "apetag.h" +#include "apefooter.h" +#include "combinedtag.h" + +using namespace TagLib; + +class WavPack::File::FilePrivate +{ +public: + FilePrivate() : + APETag(0), + APELocation(-1), + APESize(0), + ID3v1Tag(0), + ID3v1Location(-1), + tag(0), + properties(0), + scanned(false), + hasAPE(false), + hasID3v1(false) {} + + ~FilePrivate() + { + if (tag != ID3v1Tag && tag != APETag) delete tag; + delete ID3v1Tag; + delete APETag; + delete properties; + } + + APE::Tag *APETag; + long APELocation; + uint APESize; + + 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 hasAPE; + bool hasID3v1; +}; + +//////////////////////////////////////////////////////////////////////////////// +// public members +//////////////////////////////////////////////////////////////////////////////// + +WavPack::File::File(const char *file, bool readProperties, + Properties::ReadStyle propertiesStyle) : TagLib::File(file) +{ + d = new FilePrivate; + read(readProperties, propertiesStyle); +} + +WavPack::File::~File() +{ + delete d; +} + +TagLib::Tag *WavPack::File::tag() const +{ + return d->tag; +} + +WavPack::Properties *WavPack::File::audioProperties() const +{ + return d->properties; +} + +bool WavPack::File::save() +{ + if(readOnly()) { +#if 0 + debug("WavPack::File::save() -- File is read only."); +#endif + return false; + } + + // Update ID3v1 tag + + if(d->ID3v1Tag) { + if(d->hasID3v1) { + seek(d->ID3v1Location); + writeBlock(d->ID3v1Tag->render()); + } + else { + seek(0, End); + d->ID3v1Location = tell(); + writeBlock(d->ID3v1Tag->render()); + d->hasID3v1 = true; + } + } else + if(d->hasID3v1) { + removeBlock(d->ID3v1Location, 128); + d->hasID3v1 = false; + if(d->hasAPE) { + if(d->APELocation > d->ID3v1Location) + d->APELocation -= 128; + } + } + + // Update APE tag + + if(d->APETag) { + if(d->hasAPE) + insert(d->APETag->render(), d->APELocation, d->APESize); + else { + if(d->hasID3v1) { + insert(d->APETag->render(), d->ID3v1Location, 0); + d->APESize = d->APETag->footer()->completeTagSize(); + d->hasAPE = true; + d->APELocation = d->ID3v1Location; + d->ID3v1Location += d->APESize; + } + else { + seek(0, End); + d->APELocation = tell(); + writeBlock(d->APETag->render()); + d->APESize = d->APETag->footer()->completeTagSize(); + d->hasAPE = true; + } + } + } + else + if(d->hasAPE) { + removeBlock(d->APELocation, d->APESize); + d->hasAPE = false; + if(d->hasID3v1) { + if (d->ID3v1Location > d->APELocation) + d->ID3v1Location -= d->APESize; + } + } + + return true; +} + +ID3v1::Tag *WavPack::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->APETag) + d->tag = new CombinedTag(d->APETag, d->ID3v1Tag); + else + d->tag = d->ID3v1Tag; + + return d->ID3v1Tag; +} + +APE::Tag *WavPack::File::APETag(bool create) +{ + if(!create || d->APETag) + return d->APETag; + + // no APE tag exists and we've been asked to create one + + d->APETag = new APE::Tag; + + if(d->ID3v1Tag) + d->tag = new CombinedTag(d->APETag, d->ID3v1Tag); + else + d->tag = d->APETag; + + return d->APETag; +} + +void WavPack::File::remove(int tags) +{ + if(tags & ID3v1) { + delete d->ID3v1Tag; + d->ID3v1Tag = 0; + + if(d->APETag) + d->tag = d->APETag; + else + d->tag = d->APETag = new APE::Tag; + } + + if(tags & APE) { + delete d->APETag; + d->APETag = 0; + + if(d->ID3v1Tag) + d->tag = d->ID3v1Tag; + else + d->tag = d->APETag = new APE::Tag; + } +} + +//////////////////////////////////////////////////////////////////////////////// +// private members +//////////////////////////////////////////////////////////////////////////////// + +void WavPack::File::read(bool readProperties, Properties::ReadStyle /* propertiesStyle */) +{ + // Look for an ID3v1 tag + + d->ID3v1Location = findID3v1(); + + if(d->ID3v1Location >= 0) { + d->ID3v1Tag = new ID3v1::Tag(this, d->ID3v1Location); + d->hasID3v1 = true; + } + + // Look for an APE tag + + d->APELocation = findAPE(); + + if(d->APELocation >= 0) { + d->APETag = new APE::Tag(this, d->APELocation); + d->APESize = d->APETag->footer()->completeTagSize(); + d->APELocation = d->APELocation + d->APETag->footer()->size() - d->APESize; + d->hasAPE = true; + } + + if(d->hasID3v1 && d->hasAPE) + d->tag = new CombinedTag(d->APETag, d->ID3v1Tag); + else { + if(d->hasID3v1) + d->tag = d->ID3v1Tag; + else { + if(d->hasAPE) + d->tag = d->APETag; + else + d->tag = d->APETag = new APE::Tag; + } + } + + // Look for WavPack audio properties + + if(readProperties) { + seek(0); + d->properties = new Properties(readBlock(WavPack::HeaderSize), + length() - d->APESize); + } +} + +long WavPack::File::findAPE() +{ + if(!isValid()) + return -1; + + if(d->hasID3v1) + seek(-160, End); + else + seek(-32, End); + + long p = tell(); + + if(readBlock(8) == APE::Tag::fileIdentifier()) + return p; + + return -1; +} + +long WavPack::File::findID3v1() +{ + if(!isValid()) + return -1; + + seek(-128, End); + long p = tell(); + + if(readBlock(3) == ID3v1::Tag::fileIdentifier()) + return p; + + return -1; +} diff --git a/src/metadata/wavpack/wvfile.h b/src/metadata/wavpack/wvfile.h new file mode 100644 index 0000000..6c57f6d --- /dev/null +++ b/src/metadata/wavpack/wvfile.h @@ -0,0 +1,160 @@ +/*************************************************************************** + 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_WVFILE_H +#define TAGLIB_WVFILE_H + +#include "tfile.h" + +#include "wvproperties.h" + +namespace TagLib { + + class Tag; + + namespace ID3v1 { class Tag; } + namespace APE { class Tag; } + + //! An implementation of WavPack metadata + + /*! + * This is implementation of WavPack metadata. + * + * This supports ID3v1 and APE (v1 and v2) style comments as well as reading stream + * properties from the file. + */ + + namespace WavPack { + + //! An implementation of TagLib::File with WavPack specific methods + + /*! + * This implements and provides an interface for WavPack 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 WavPack 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 APE tags. + APE = 0x0002, + //! Matches all tag types. + AllTags = 0xffff + }; + + /*! + * Contructs an WavPack 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); + + /*! + * 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; + + /*! + * Saves the file. + */ + virtual bool save(); + + /*! + * 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 APE::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 APE tag of the file. + * + * If \a create is false (the default) this will return a null pointer + * if there is no valid APE tag. If \a create is true it will create + * a APE tag if one does not exist. + * + * \note The Tag <b>is still</b> owned by the APE::File and should not be + * deleted by the user. It will be deleted when the file (object) is + * destroyed. + */ + APE::Tag *APETag(bool create = false); + + /*! + * This will remove the tags that match the OR-ed together TagTypes from the + * file. By default it removes all tags. + * + * \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 findAPE(); + + class FilePrivate; + FilePrivate *d; + }; + } +} + +#endif diff --git a/src/metadata/wavpack/wvproperties.cpp b/src/metadata/wavpack/wvproperties.cpp new file mode 100644 index 0000000..376824d --- /dev/null +++ b/src/metadata/wavpack/wvproperties.cpp @@ -0,0 +1,141 @@ +/*************************************************************************** + 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 "wvproperties.h" +#include "wvfile.h" + +using namespace TagLib; + +class WavPack::Properties::PropertiesPrivate +{ +public: + PropertiesPrivate(const ByteVector &d, long length, ReadStyle s) : + data(d), + streamLength(length), + style(s), + length(0), + bitrate(0), + sampleRate(0), + channels(0), + version(0), + bitsPerSample(0) {} + + ByteVector data; + long streamLength; + ReadStyle style; + int length; + int bitrate; + int sampleRate; + int channels; + int version; + int bitsPerSample; +}; + +//////////////////////////////////////////////////////////////////////////////// +// public members +//////////////////////////////////////////////////////////////////////////////// + +WavPack::Properties::Properties(const ByteVector &data, long streamLength, ReadStyle style) : AudioProperties(style) +{ + d = new PropertiesPrivate(data, streamLength, style); + read(); +} + +WavPack::Properties::~Properties() +{ + delete d; +} + +int WavPack::Properties::length() const +{ + return d->length; +} + +int WavPack::Properties::bitrate() const +{ + return d->bitrate; +} + +int WavPack::Properties::sampleRate() const +{ + return d->sampleRate; +} + +int WavPack::Properties::channels() const +{ + return d->channels; +} + +int WavPack::Properties::version() const +{ + return d->version; +} + +int WavPack::Properties::bitsPerSample() const +{ + return d->bitsPerSample; +} + +//////////////////////////////////////////////////////////////////////////////// +// private members +//////////////////////////////////////////////////////////////////////////////// + +static const unsigned int sample_rates[] = { 6000, 8000, 9600, 11025, 12000, + 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000, 192000 }; + +#define BYTES_STORED 3 +#define MONO_FLAG 4 + +#define SHIFT_LSB 13 +#define SHIFT_MASK (0x1fL << SHIFT_LSB) + +#define SRATE_LSB 23 +#define SRATE_MASK (0xfL << SRATE_LSB) + +void WavPack::Properties::read() +{ + if(!d->data.startsWith("wvpk")) + return; + + d->version = d->data.mid(8, 2).toShort(false); + + unsigned int flags = d->data.mid(24, 4).toUInt(false); + d->bitsPerSample = ((flags & BYTES_STORED) + 1) * 8 - + ((flags & SHIFT_MASK) >> SHIFT_LSB); + d->sampleRate = sample_rates[(flags & SRATE_MASK) >> SRATE_LSB]; + d->channels = (flags & MONO_FLAG) ? 1 : 2; + + unsigned int samples = d->data.mid(12, 4).toUInt(false); + d->length = d->sampleRate > 0 ? (samples + (d->sampleRate / 2)) / d->sampleRate : 0; + + d->bitrate = d->length > 0 ? ((d->streamLength * 8L) / d->length) / 1000 : 0; +} + diff --git a/src/metadata/wavpack/wvproperties.h b/src/metadata/wavpack/wvproperties.h new file mode 100644 index 0000000..b615adf --- /dev/null +++ b/src/metadata/wavpack/wvproperties.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_WVPROPERTIES_H +#define TAGLIB_WVPROPERTIES_H + +#include "audioproperties.h" + +namespace TagLib { + + namespace WavPack { + + class File; + + static const uint HeaderSize = 32; + + //! An implementation of audio property reading for WavPack + + /*! + * This reads the data from an WavPack stream found in the AudioProperties + * API. + */ + + class Properties : public AudioProperties + { + public: + /*! + * Create an instance of WavPack::Properties with the data read from the + * ByteVector \a data. + */ + Properties(const ByteVector &data, long streamLength, ReadStyle style = Average); + + /*! + * Destroys this WavPack::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 WavPack version. + */ + int version() const; + + private: + void read(); + + class PropertiesPrivate; + PropertiesPrivate *d; + }; + } +} + +#endif |