This commit is contained in:
gonemad
2012-10-18 20:17:35 -04:00
13 changed files with 584 additions and 2 deletions

View File

@ -0,0 +1,126 @@
/***************************************************************************
copyright : (C) 2012 by Lukáš Lalinský
email : lalinsky@gmail.com
copyright : (C) 2002 - 2008 by Scott Wheeler
email : wheeler@kde.org
(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 *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#include <bitset>
#include <tstring.h>
#include <tdebug.h>
#include "opusfile.h"
using namespace TagLib;
using namespace TagLib::Ogg;
class Opus::File::FilePrivate
{
public:
FilePrivate() :
comment(0),
properties(0) {}
~FilePrivate()
{
delete comment;
delete properties;
}
Ogg::XiphComment *comment;
Properties *properties;
};
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
Opus::File::File(FileName file, bool readProperties,
Properties::ReadStyle propertiesStyle) : Ogg::File(file)
{
d = new FilePrivate;
read(readProperties, propertiesStyle);
}
Opus::File::File(IOStream *stream, bool readProperties,
Properties::ReadStyle propertiesStyle) : Ogg::File(stream)
{
d = new FilePrivate;
read(readProperties, propertiesStyle);
}
Opus::File::~File()
{
delete d;
}
Ogg::XiphComment *Opus::File::tag() const
{
return d->comment;
}
Opus::Properties *Opus::File::audioProperties() const
{
return d->properties;
}
bool Opus::File::save()
{
if(!d->comment)
d->comment = new Ogg::XiphComment;
setPacket(1, ByteVector("OpusTags", 8) + d->comment->render(false));
return Ogg::File::save();
}
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////
void Opus::File::read(bool readProperties, Properties::ReadStyle propertiesStyle)
{
ByteVector opusHeaderData = packet(0);
if(!opusHeaderData.startsWith("OpusHead")) {
setValid(false);
debug("Opus::File::read() -- invalid Opus identification header");
return;
}
ByteVector commentHeaderData = packet(1);
if(!commentHeaderData.startsWith("OpusTags")) {
setValid(false);
debug("Opus::File::read() -- invalid Opus tags header");
return;
}
d->comment = new Ogg::XiphComment(commentHeaderData.mid(8));
if(readProperties)
d->properties = new Properties(this, propertiesStyle);
}

110
taglib/ogg/opus/opusfile.h Normal file
View File

@ -0,0 +1,110 @@
/***************************************************************************
copyright : (C) 2012 by Lukáš Lalinský
email : lalinsky@gmail.com
copyright : (C) 2002 - 2008 by Scott Wheeler
email : wheeler@kde.org
(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 *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifndef TAGLIB_OPUSFILE_H
#define TAGLIB_OPUSFILE_H
#include "oggfile.h"
#include "xiphcomment.h"
#include "opusproperties.h"
namespace TagLib {
namespace Ogg {
//! A namespace containing classes for Opus metadata
namespace Opus {
//! An implementation of Ogg::File with Opus specific methods
/*!
* This is the central class in the Ogg Opus 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 Opus specifically.
*/
class TAGLIB_EXPORT File : public Ogg::File
{
public:
/*!
* Contructs a Opus 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);
/*!
* Contructs a Opus 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.
*
* \note TagLib will *not* take ownership of the stream, the caller is
* responsible for deleting it after the File object.
*/
File(IOStream *stream, 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 Opus::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

View File

@ -0,0 +1,161 @@
/***************************************************************************
copyright : (C) 2012 by Lukáš Lalinský
email : lalinsky@gmail.com
copyright : (C) 2002 - 2008 by Scott Wheeler
email : wheeler@kde.org
(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 *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#include <tstring.h>
#include <tdebug.h>
#include <oggpageheader.h>
#include "opusproperties.h"
#include "opusfile.h"
using namespace TagLib;
using namespace TagLib::Ogg;
class Opus::Properties::PropertiesPrivate
{
public:
PropertiesPrivate(File *f, ReadStyle s) :
file(f),
style(s),
length(0),
inputSampleRate(0),
channels(0),
opusVersion(0) {}
File *file;
ReadStyle style;
int length;
int inputSampleRate;
int channels;
int opusVersion;
};
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
Opus::Properties::Properties(File *file, ReadStyle style) : AudioProperties(style)
{
d = new PropertiesPrivate(file, style);
read();
}
Opus::Properties::~Properties()
{
delete d;
}
int Opus::Properties::length() const
{
return d->length;
}
int Opus::Properties::bitrate() const
{
return 0;
}
int Opus::Properties::sampleRate() const
{
// Opus can decode any stream at a sample rate of 8, 12, 16, 24, or 48 kHz,
// so there is no single sample rate. Let's assume it's the highest
// possible.
return 48000;
}
int Opus::Properties::channels() const
{
return d->channels;
}
int Opus::Properties::inputSampleRate() const
{
return d->inputSampleRate;
}
int Opus::Properties::opusVersion() const
{
return d->opusVersion;
}
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////
void Opus::Properties::read()
{
// Get the identification header from the Ogg implementation.
// http://tools.ietf.org/html/draft-terriberry-oggopus-01#section-5.1
ByteVector data = d->file->packet(0);
// *Magic Signature*
int pos = 8;
// *Version* (8 bits, unsigned)
d->opusVersion = uchar(data.at(pos));
pos += 1;
// *Output Channel Count* 'C' (8 bits, unsigned)
d->channels = uchar(data.at(pos));
pos += 1;
// *Pre-skip* (16 bits, unsigned, little endian)
ushort preSkip = data.mid(pos, 2).toUShort(false);
pos += 2;
// *Input Sample Rate* (32 bits, unsigned, little endian)
d->inputSampleRate = data.mid(pos, 4).toUInt(false);
pos += 4;
// *Output Gain* (16 bits, signed, little endian)
pos += 2;
// *Channel Mapping Family* (8 bits, unsigned)
pos += 1;
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->length = (int) ((end - start - preSkip) / 48000);
else {
debug("Opus::Properties::read() -- The PCM values for the start or "
"end of this file was incorrect.");
}
}
else
debug("Opus::Properties::read() -- Could not find valid first and last Ogg pages.");
}

View File

@ -0,0 +1,96 @@
/***************************************************************************
copyright : (C) 2012 by Lukáš Lalinský
email : lalinsky@gmail.com
copyright : (C) 2002 - 2008 by Scott Wheeler
email : wheeler@kde.org
(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 *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifndef TAGLIB_OPUSPROPERTIES_H
#define TAGLIB_OPUSPROPERTIES_H
#include "audioproperties.h"
namespace TagLib {
namespace Ogg {
namespace Opus {
class File;
//! An implementation of audio property reading for Ogg Opus
/*!
* This reads the data from an Ogg Opus stream found in the AudioProperties
* API.
*/
class TAGLIB_EXPORT Properties : public AudioProperties
{
public:
/*!
* Create an instance of Opus::Properties with the data read from the
* Opus::File \a file.
*/
Properties(File *file, ReadStyle style = Average);
/*!
* Destroys this Opus::Properties instance.
*/
virtual ~Properties();
// Reimplementations.
virtual int length() const;
virtual int bitrate() const;
virtual int sampleRate() const;
virtual int channels() const;
/*!
* The Opus codec supports decoding at multiple sample rates, there is no
* single sample rate of the encoded stream. This returns the sample rate
* of the original audio stream.
*/
int inputSampleRate() const;
/*!
* Returns the Opus version, currently "0" (as specified by the spec).
*/
int opusVersion() const;
private:
Properties(const Properties &);
Properties &operator=(const Properties &);
void read();
class PropertiesPrivate;
PropertiesPrivate *d;
};
}
}
}
#endif