diff options
Diffstat (limited to 'src/metadata/speex')
-rw-r--r-- | src/metadata/speex/Makefile.am | 16 | ||||
-rw-r--r-- | src/metadata/speex/speexfile.cpp | 111 | ||||
-rw-r--r-- | src/metadata/speex/speexfile.h | 93 | ||||
-rw-r--r-- | src/metadata/speex/speexproperties.cpp | 171 | ||||
-rw-r--r-- | src/metadata/speex/speexproperties.h | 83 | ||||
-rw-r--r-- | src/metadata/speex/taglib_speexfiletyperesolver.cpp | 44 | ||||
-rw-r--r-- | src/metadata/speex/taglib_speexfiletyperesolver.h | 36 |
7 files changed, 554 insertions, 0 deletions
diff --git a/src/metadata/speex/Makefile.am b/src/metadata/speex/Makefile.am new file mode 100644 index 0000000..6bf01aa --- /dev/null +++ b/src/metadata/speex/Makefile.am @@ -0,0 +1,16 @@ +SUBDIRS = + +INCLUDES = $(all_includes) $(taglib_includes) +METASOURCES = AUTO +libtagspeex_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libtagspeex.la + +libtagspeex_la_SOURCES = \ + speexfile.cpp \ + speexproperties.cpp \ + taglib_speexfiletyperesolver.cpp + +noinst_HEADERS = speexfile.h \ + speexproperties.h \ + taglib_speexfiletyperesolver.h + diff --git a/src/metadata/speex/speexfile.cpp b/src/metadata/speex/speexfile.cpp new file mode 100644 index 0000000..eccaded --- /dev/null +++ b/src/metadata/speex/speexfile.cpp @@ -0,0 +1,111 @@ +/*************************************************************************** + copyright : (C) 2006 by Lukáš Lalinský + email : [email protected] + + copyright : (C) 2002 by Scott Wheeler + email : [email protected] + (original Vorbis 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 <bitset> + +#include <tstring.h> +#if 0 +#include <tdebug.h> +#endif + +#include "speexfile.h" + +using namespace TagLib; + +class Speex::File::FilePrivate +{ +public: + FilePrivate() : + comment(0), + properties(0) {} + + ~FilePrivate() + { + delete comment; + delete properties; + } + + Ogg::XiphComment *comment; + Properties *properties; +}; + +//////////////////////////////////////////////////////////////////////////////// +// public members +//////////////////////////////////////////////////////////////////////////////// + +Speex::File::File(const char *file, bool readProperties, + Properties::ReadStyle propertiesStyle) : Ogg::File(file) +{ + d = new FilePrivate; + read(readProperties, propertiesStyle); +} + +Speex::File::~File() +{ + delete d; +} + +Ogg::XiphComment *Speex::File::tag() const +{ + return d->comment; +} + +Speex::Properties *Speex::File::audioProperties() const +{ + return d->properties; +} + +bool Speex::File::save() +{ + if(!d->comment) + d->comment = new Ogg::XiphComment; + + setPacket(1, d->comment->render()); + + return Ogg::File::save(); +} + +//////////////////////////////////////////////////////////////////////////////// +// private members +//////////////////////////////////////////////////////////////////////////////// + +void Speex::File::read(bool readProperties, Properties::ReadStyle propertiesStyle) +{ + ByteVector speexHeaderData = packet(0); + + if(!speexHeaderData.startsWith("Speex ")) { +#if 0 + debug("Speex::File::read() -- invalid Speex identification header"); +#endif + return; + } + + ByteVector commentHeaderData = packet(1); + + d->comment = new Ogg::XiphComment(commentHeaderData); + + if(readProperties) + d->properties = new Properties(this, propertiesStyle); +} diff --git a/src/metadata/speex/speexfile.h b/src/metadata/speex/speexfile.h new file mode 100644 index 0000000..d300ac3 --- /dev/null +++ b/src/metadata/speex/speexfile.h @@ -0,0 +1,93 @@ +/*************************************************************************** + copyright : (C) 2006 by Lukáš Lalinský + email : [email protected] + + copyright : (C) 2002 by Scott Wheeler + email : [email protected] + (original Vorbis 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_SPEEXFILE_H +#define TAGLIB_SPEEXFILE_H + +#include <oggfile.h> +#include <xiphcomment.h> + +#include "speexproperties.h" + +namespace TagLib { + + //! A namespace containing classes for Speex metadata + + namespace Speex { + + //! An implementation of Ogg::File with Speex specific methods + + /*! + * This is the central class in the Ogg Speex metadata processing collection + * of classes. It's built upon Ogg::File which handles processing of the Ogg + * logical bitstream and breaking it down into pages which are handled by + * the codec implementations, in this case Speex specifically. + */ + + class File : public Ogg::File + { + public: + /*! + * Contructs a Speex 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 XiphComment for this file. XiphComment implements the tag + * interface, so this serves as the reimplementation of + * TagLib::File::tag(). + */ + virtual Ogg::XiphComment *tag() const; + + /*! + * Returns the Speex::Properties for this file. If no audio properties + * were read then this will return a null pointer. + */ + virtual Properties *audioProperties() const; + + virtual bool save(); + + private: + File(const File &); + File &operator=(const File &); + + void read(bool readProperties, Properties::ReadStyle propertiesStyle); + + class FilePrivate; + FilePrivate *d; + }; + } + +} + +#endif diff --git a/src/metadata/speex/speexproperties.cpp b/src/metadata/speex/speexproperties.cpp new file mode 100644 index 0000000..edd2b71 --- /dev/null +++ b/src/metadata/speex/speexproperties.cpp @@ -0,0 +1,171 @@ +/*************************************************************************** + copyright : (C) 2006 by Lukáš Lalinský + email : [email protected] + + copyright : (C) 2002 by Scott Wheeler + email : [email protected] + (original Vorbis 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 <oggpageheader.h> + +#include "speexproperties.h" +#include "speexfile.h" + +using namespace TagLib; + +class Speex::Properties::PropertiesPrivate +{ +public: + PropertiesPrivate(File *f, ReadStyle s) : + file(f), + style(s), + length(0), + bitrate(0), + sampleRate(0), + channels(0), + speexVersion(0), + vbr(false), + mode(0) {} + + File *file; + ReadStyle style; + int length; + int bitrate; + int sampleRate; + int channels; + int speexVersion; + bool vbr; + int mode; +}; + +//////////////////////////////////////////////////////////////////////////////// +// public members +//////////////////////////////////////////////////////////////////////////////// + +Speex::Properties::Properties(File *file, ReadStyle style) : AudioProperties(style) +{ + d = new PropertiesPrivate(file, style); + read(); +} + +Speex::Properties::~Properties() +{ + delete d; +} + +int Speex::Properties::length() const +{ + return d->length; +} + +int Speex::Properties::bitrate() const +{ + return int(float(d->bitrate) / float(1000) + 0.5); +} + +int Speex::Properties::sampleRate() const +{ + return d->sampleRate; +} + +int Speex::Properties::channels() const +{ + return d->channels; +} + +int Speex::Properties::speexVersion() const +{ + return d->speexVersion; +} + +//////////////////////////////////////////////////////////////////////////////// +// private members +//////////////////////////////////////////////////////////////////////////////// + +void Speex::Properties::read() +{ + // Get the identification header from the Ogg implementation. + + ByteVector data = d->file->packet(0); + + int pos = 28; + + // speex_version_id; /**< Version for Speex (for checking compatibility) */ + d->speexVersion = data.mid(pos, 4).toUInt(false); + pos += 4; + + // header_size; /**< Total size of the header ( sizeof(SpeexHeader) ) */ + pos += 4; + + // rate; /**< Sampling rate used */ + d->sampleRate = data.mid(pos, 4).toUInt(false); + pos += 4; + + // mode; /**< Mode used (0 for narrowband, 1 for wideband) */ + d->mode = data.mid(pos, 4).toUInt(false); + pos += 4; + + // mode_bitstream_version; /**< Version ID of the bit-stream */ + pos += 4; + + // nb_channels; /**< Number of channels encoded */ + d->channels = data.mid(pos, 4).toUInt(false); + pos += 4; + + // bitrate; /**< Bit-rate used */ + d->bitrate = data.mid(pos, 4).toUInt(false); + pos += 4; + + // frame_size; /**< Size of frames */ + //unsigned int frameSize = data.mid(pos, 4).toUInt(false); + pos += 4; + + // vbr; /**< 1 for a VBR encoding, 0 otherwise */ + d->vbr = data.mid(pos, 4).toUInt(false) == 1; + pos += 4; + + // frames_per_packet; /**< Number of frames stored per Ogg packet */ + //unsigned int framesPerPacket = data.mid(pos, 4).toUInt(false); + + const Ogg::PageHeader *first = d->file->firstPageHeader(); + const Ogg::PageHeader *last = d->file->lastPageHeader(); + + if(first && last) { + long long start = first->absoluteGranularPosition(); + long long end = last->absoluteGranularPosition(); + + if(start >= 0 && end >= 0 && d->sampleRate > 0) + d->length = (end - start) / (long long) d->sampleRate; +#if 0 + else + debug("Speex::Properties::read() -- Either the PCM values for the start or " + "end of this file was incorrect or the sample rate is zero."); +#endif + } +#if 0 + else + debug("Speex::Properties::read() -- Could not find valid first and last Ogg pages."); +#endif +} diff --git a/src/metadata/speex/speexproperties.h b/src/metadata/speex/speexproperties.h new file mode 100644 index 0000000..355ff3c --- /dev/null +++ b/src/metadata/speex/speexproperties.h @@ -0,0 +1,83 @@ +/*************************************************************************** + copyright : (C) 2006 by Lukáš Lalinský + email : [email protected] + + copyright : (C) 2002 by Scott Wheeler + email : [email protected] + (original Vorbis 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_SPEEXPROPERTIES_H +#define TAGLIB_SPEEXPROPERTIES_H + +#include <audioproperties.h> + +namespace TagLib { + + namespace Speex { + + class File; + + //! An implementation of audio property reading for Ogg Speex + + /*! + * This reads the data from an Ogg Speex stream found in the AudioProperties + * API. + */ + + class Properties : public AudioProperties + { + public: + /*! + * Create an instance of Vorbis::Properties with the data read from the + * Vorbis::File \a file. + */ + Properties(File *file, ReadStyle style = Average); + + /*! + * Destroys this VorbisProperties instance. + */ + virtual ~Properties(); + + // Reimplementations. + + virtual int length() const; + virtual int bitrate() const; + virtual int sampleRate() const; + virtual int channels() const; + + /*! + * Returns the Vorbis version, currently "0" (as specified by the spec). + */ + int speexVersion() const; + + private: + Properties(const Properties &); + Properties &operator=(const Properties &); + + void read(); + + class PropertiesPrivate; + PropertiesPrivate *d; + }; + } + +} + +#endif diff --git a/src/metadata/speex/taglib_speexfiletyperesolver.cpp b/src/metadata/speex/taglib_speexfiletyperesolver.cpp new file mode 100644 index 0000000..9a5de0d --- /dev/null +++ b/src/metadata/speex/taglib_speexfiletyperesolver.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_speexfiletyperesolver.h" +#include "speexfile.h" + +#include <string.h> + +TagLib::File *SpeexFileTypeResolver::createFile(const char *fileName, + bool readProperties, + TagLib::AudioProperties::ReadStyle propertiesStyle) const +{ + const char *ext = strrchr(fileName, '.'); + if(ext && !strcasecmp(ext, ".spx")) + { + TagLib::Speex::File *f = new TagLib::Speex::File(fileName, readProperties, propertiesStyle); + if(f->isValid()) + return f; + else + { + delete f; + } + } + + return 0; +} diff --git a/src/metadata/speex/taglib_speexfiletyperesolver.h b/src/metadata/speex/taglib_speexfiletyperesolver.h new file mode 100644 index 0000000..b5c5c2c --- /dev/null +++ b/src/metadata/speex/taglib_speexfiletyperesolver.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_SPEEXFILETYPERESOLVER_H +#define TAGLIB_SPEEXFILETYPERESOLVER_H + +#include <taglib/tfile.h> +#include <taglib/fileref.h> + + +class SpeexFileTypeResolver : public TagLib::FileRef::FileTypeResolver +{ + TagLib::File *createFile(const char *fileName, + bool readAudioProperties, + TagLib::AudioProperties::ReadStyle audioPropertiesStyle) const; +}; + +#endif |