mirror of
https://github.com/taglib/taglib.git
synced 2025-05-27 21:20:26 -04:00
Adding Ogg/FLAC support to TagLib
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@301825 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
This commit is contained in:
parent
4f1f6adf59
commit
1bc8909bba
@ -1,4 +1,4 @@
|
||||
SUBDIRS = vorbis
|
||||
SUBDIRS = vorbis flac
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/taglib -I$(top_srcdir)/taglib/toolkit $(all_includes)
|
||||
|
||||
@ -18,6 +18,6 @@ taglib_include_HEADERS = \
|
||||
|
||||
taglib_includedir = $(includedir)/taglib
|
||||
|
||||
libogg_la_LIBADD = ./vorbis/libvorbis.la
|
||||
libogg_la_LIBADD = ./vorbis/libvorbis.la ./flac/liboggflac.la
|
||||
|
||||
EXTRA_DIST = $(libogg_la_SOURCES) $(taglib_include_HEADERS)
|
||||
|
15
ogg/flac/Makefile.am
Normal file
15
ogg/flac/Makefile.am
Normal file
@ -0,0 +1,15 @@
|
||||
INCLUDES = \
|
||||
-I$(top_srcdir)/taglib \
|
||||
-I$(top_srcdir)/taglib/toolkit \
|
||||
-I$(top_srcdir)/taglib/ogg \
|
||||
-I$(top_srcdir)/taglib/flac \
|
||||
$(all_includes)
|
||||
|
||||
noinst_LTLIBRARIES = liboggflac.la
|
||||
|
||||
liboggflac_la_SOURCES = oggflacfile.cpp
|
||||
|
||||
taglib_include_HEADERS = oggflacfile.h
|
||||
taglib_includedir = $(includedir)/taglib
|
||||
|
||||
EXTRA_DIST = $(liboggflac_la_SOURCES) $(taglib_include_HEADERS)
|
247
ogg/flac/oggflacfile.cpp
Normal file
247
ogg/flac/oggflacfile.cpp
Normal file
@ -0,0 +1,247 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2004 by Allan Sandfeld Jensen
|
||||
email : kde@carewolf.org
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
* USA *
|
||||
***************************************************************************/
|
||||
|
||||
#include <tbytevector.h>
|
||||
#include <tstring.h>
|
||||
#include <tdebug.h>
|
||||
|
||||
#include <xiphcomment.h>
|
||||
#include "oggflacfile.h"
|
||||
|
||||
using namespace TagLib;
|
||||
using TagLib::FLAC::Properties;
|
||||
|
||||
class Ogg::FLAC::File::FilePrivate
|
||||
{
|
||||
public:
|
||||
FilePrivate() :
|
||||
comment(0),
|
||||
properties(0),
|
||||
streamStart(0),
|
||||
streamLength(0),
|
||||
scanned(false),
|
||||
hasXiphComment(false),
|
||||
commentPacket(0) {}
|
||||
|
||||
~FilePrivate()
|
||||
{
|
||||
delete comment;
|
||||
delete properties;
|
||||
}
|
||||
|
||||
Ogg::XiphComment *comment;
|
||||
|
||||
Properties *properties;
|
||||
ByteVector streamInfoData;
|
||||
ByteVector xiphCommentData;
|
||||
long streamStart;
|
||||
long streamLength;
|
||||
bool scanned;
|
||||
|
||||
bool hasXiphComment;
|
||||
int commentPacket;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Ogg::FLAC::File::File(const char *file, bool readProperties,
|
||||
Properties::ReadStyle propertiesStyle) : Ogg::File(file)
|
||||
{
|
||||
d = new FilePrivate;
|
||||
read(readProperties, propertiesStyle);
|
||||
}
|
||||
|
||||
Ogg::FLAC::File::~File()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
TagLib::Tag* Ogg::FLAC::File::tag() const
|
||||
{
|
||||
return d->comment;
|
||||
}
|
||||
|
||||
Properties* Ogg::FLAC::File::audioProperties() const
|
||||
{
|
||||
return d->properties;
|
||||
}
|
||||
|
||||
|
||||
void Ogg::FLAC::File::save()
|
||||
{
|
||||
d->xiphCommentData = d->comment->render();
|
||||
|
||||
// Create FLAC metadata-block:
|
||||
|
||||
// Put the size in the first 32 bit ( I assume no more than 24 bit are used )
|
||||
|
||||
ByteVector v = ByteVector::fromUInt(d->xiphCommentData.size());
|
||||
|
||||
// Set the type of the metadata-block to be a Xiph / Vorbis comment
|
||||
|
||||
v[0] = 4;
|
||||
|
||||
// Append the comment-data after the 32 bit header
|
||||
|
||||
v.append(d->xiphCommentData);
|
||||
|
||||
// Save the packet at the old spot
|
||||
// FIXME: Use padding if size is increasing
|
||||
|
||||
setPacket(d->commentPacket, v);
|
||||
|
||||
Ogg::File::save();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// private members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Ogg::FLAC::File::read(bool readProperties, Properties::ReadStyle propertiesStyle)
|
||||
{
|
||||
// Sanity: Check if we really have an Ogg/FLAC file
|
||||
|
||||
/*
|
||||
ByteVector oggHeader = packet(0);
|
||||
|
||||
if (oggHeader.mid(28,4) != "fLaC") {
|
||||
debug("Ogg::FLAC::File::read() -- Not an Ogg/FLAC file");
|
||||
setValid(false);
|
||||
return;
|
||||
}*/
|
||||
|
||||
// Look for FLAC metadata, including vorbis comments
|
||||
|
||||
scan();
|
||||
|
||||
if (!d->scanned) {
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(d->hasXiphComment)
|
||||
d->comment = new Ogg::XiphComment(xiphCommentData());
|
||||
else {
|
||||
d->comment = new Ogg::XiphComment();
|
||||
}
|
||||
|
||||
|
||||
if(readProperties)
|
||||
d->properties = new Properties(streamInfoData(), streamLength(), propertiesStyle);
|
||||
}
|
||||
|
||||
ByteVector Ogg::FLAC::File::streamInfoData()
|
||||
{
|
||||
scan();
|
||||
return d->streamInfoData;
|
||||
}
|
||||
|
||||
ByteVector Ogg::FLAC::File::xiphCommentData()
|
||||
{
|
||||
scan();
|
||||
return d->xiphCommentData;
|
||||
}
|
||||
|
||||
long Ogg::FLAC::File::streamLength()
|
||||
{
|
||||
scan();
|
||||
return d->streamLength;
|
||||
}
|
||||
|
||||
void Ogg::FLAC::File::scan()
|
||||
{
|
||||
// Scan the metadata pages
|
||||
|
||||
if(d->scanned)
|
||||
return;
|
||||
|
||||
if(!isValid())
|
||||
return;
|
||||
|
||||
int ipacket = 1;
|
||||
long overhead = 0;
|
||||
|
||||
ByteVector metadataHeader = packet(ipacket);
|
||||
|
||||
if (metadataHeader == ByteVector::null)
|
||||
return;
|
||||
|
||||
ByteVector header = metadataHeader.mid(0,4);
|
||||
|
||||
// Header format (from spec):
|
||||
// <1> Last-metadata-block flag
|
||||
// <7> BLOCK_TYPE
|
||||
// 0 : STREAMINFO
|
||||
// 1 : PADDING
|
||||
// ..
|
||||
// 4 : VORBIS_COMMENT
|
||||
// ..
|
||||
// <24> Length of metadata to follow
|
||||
|
||||
char blockType = header[0] & 0x7f;
|
||||
bool lastBlock = header[0] & 0x80;
|
||||
uint length = header.mid(1, 3).toUInt();
|
||||
overhead += length;
|
||||
|
||||
// Sanity: First block should be the stream_info metadata
|
||||
|
||||
if(blockType != 0) {
|
||||
debug("Ogg::FLAC::File::scan() -- Invalid Ogg/FLAC stream");
|
||||
return;
|
||||
}
|
||||
|
||||
d->streamInfoData = metadataHeader.mid(4,length);
|
||||
|
||||
// Search through the remaining metadata
|
||||
|
||||
while(!lastBlock) {
|
||||
metadataHeader = packet(++ipacket);
|
||||
|
||||
header = metadataHeader.mid(0, 4);
|
||||
blockType = header[0] & 0x7f;
|
||||
lastBlock = header[0] & 0x80;
|
||||
length = header.mid(1, 3).toUInt();
|
||||
overhead += length;
|
||||
|
||||
if(blockType == 1) {
|
||||
// debug("Ogg::FLAC::File::scan() -- Padding found");
|
||||
} else
|
||||
if(blockType == 4) {
|
||||
// debug("Ogg::FLAC::File::scan() -- Vorbis-comments found");
|
||||
d->xiphCommentData = metadataHeader.mid(4, length);
|
||||
d->hasXiphComment = true;
|
||||
d->commentPacket = ipacket;
|
||||
} else
|
||||
if(blockType > 5) {
|
||||
debug("Ogg::FLAC::File::scan() -- Unknown metadata block");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// End of metadata, now comes the datastream
|
||||
d->streamStart = overhead;
|
||||
d->streamLength = File::length() - d->streamStart;
|
||||
|
||||
d->scanned = true;
|
||||
}
|
110
ogg/flac/oggflacfile.h
Normal file
110
ogg/flac/oggflacfile.h
Normal file
@ -0,0 +1,110 @@
|
||||
/***************************************************************************
|
||||
copyright : (C) 2004 by Allan Sandfeld Jensen
|
||||
email : kde@carewolf.org
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
* USA *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef TAGLIB_OGGFLACFILE_H
|
||||
#define TAGLIB_OGGFLACFILE_H
|
||||
|
||||
#include <oggfile.h>
|
||||
|
||||
#include <flacproperties.h>
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
class Tag;
|
||||
|
||||
//! An implementation of Ogg/FLAC metadata
|
||||
|
||||
/*!
|
||||
* This is implementation of FLAC metadata for Ogg/FLAC files. For native
|
||||
* FLAC files look under the FLAC hiearchy.
|
||||
*
|
||||
* Unlike native FLAC-files, Ogg/FLAC only supports Xiph-comments,
|
||||
* while the audio-properties are the same.
|
||||
*/
|
||||
|
||||
namespace Ogg {
|
||||
namespace FLAC {
|
||||
|
||||
using TagLib::FLAC::Properties;
|
||||
|
||||
//! An implementation of TagLib::File with Ogg/FLAC specific methods
|
||||
|
||||
/*!
|
||||
* This implements and provides an interface for Ogg/FLAC 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 Ogg/FLAC files.
|
||||
*/
|
||||
|
||||
class File : public TagLib::Ogg::File
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Contructs an Ogg/FLAC 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 always be a XiphComment.
|
||||
*/
|
||||
virtual TagLib::Tag *tag() const;
|
||||
|
||||
/*!
|
||||
* Returns the FLAC::Properties for this file. If no audio properties
|
||||
* were read then this will return a null pointer.
|
||||
*/
|
||||
virtual Properties *audioProperties() const;
|
||||
|
||||
/*!
|
||||
* Save the file. This will primarily save and update the XiphComment.
|
||||
*/
|
||||
virtual void save();
|
||||
|
||||
/*!
|
||||
* Returns the length of the audio-stream, used by FLAC::Properties for
|
||||
* calculating the bitrate.
|
||||
*/
|
||||
long streamLength();
|
||||
|
||||
private:
|
||||
File(const File &);
|
||||
File &operator=(const File &);
|
||||
|
||||
void read(bool readProperties, Properties::ReadStyle propertiesStyle);
|
||||
void scan();
|
||||
ByteVector streamInfoData();
|
||||
ByteVector xiphCommentData();
|
||||
|
||||
class FilePrivate;
|
||||
FilePrivate *d;
|
||||
};
|
||||
} // namespace FLAC
|
||||
} // namespace Ogg
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user