Implement Matroska audio properties

This commit is contained in:
Urs Fleisch
2025-08-16 11:19:25 +02:00
parent f7ab162514
commit cfade6d082
16 changed files with 565 additions and 14 deletions

View File

@ -245,9 +245,12 @@ if(WITH_MATROSKA)
matroska/ebml/ebmlmkcues.h
matroska/ebml/ebmlmkseekhead.h
matroska/ebml/ebmlmksegment.h
matroska/ebml/ebmlmkinfo.h
matroska/ebml/ebmlmktracks.h
matroska/ebml/ebmlmktags.h
matroska/ebml/ebmlstringelement.h
matroska/ebml/ebmluintelement.h
matroska/ebml/ebmlfloatelement.h
matroska/ebml/ebmlutils.h
matroska/ebml/ebmlvoidelement.h
)
@ -464,9 +467,12 @@ if(WITH_MATROSKA)
matroska/ebml/ebmlmkcues.cpp
matroska/ebml/ebmlmkseekhead.cpp
matroska/ebml/ebmlmksegment.cpp
matroska/ebml/ebmlmkinfo.cpp
matroska/ebml/ebmlmktracks.cpp
matroska/ebml/ebmlmktags.cpp
matroska/ebml/ebmlstringelement.cpp
matroska/ebml/ebmluintelement.cpp
matroska/ebml/ebmlfloatelement.cpp
matroska/ebml/ebmlutils.cpp
matroska/ebml/ebmlvoidelement.cpp
)

View File

@ -22,10 +22,12 @@
#include "ebmlvoidelement.h"
#include "ebmlmasterelement.h"
#include "ebmlbinaryelement.h"
#include "ebmlfloatelement.h"
#include "ebmlmkseekhead.h"
#include "ebmlmksegment.h"
#include "ebmlmktags.h"
#include "ebmlmkattachments.h"
#include "ebmlmktracks.h"
#include "ebmlstringelement.h"
#include "ebmluintelement.h"
#include "ebmlutils.h"
@ -60,6 +62,12 @@ EBML::Element *EBML::Element::factory(File &file)
case ElementIDs::MkSegment:
return new MkSegment(sizeLength, dataSize, offset);
case ElementIDs::MkInfo:
return new MkInfo(sizeLength, dataSize, offset);
case ElementIDs::MkTracks:
return new MkTracks(sizeLength, dataSize, offset);
case ElementIDs::MkTags:
return new MkTags(sizeLength, dataSize, offset);
@ -71,6 +79,8 @@ EBML::Element *EBML::Element::factory(File &file)
case ElementIDs::MkSimpleTag:
case ElementIDs::MkAttachedFile:
case ElementIDs::MkSeek:
case ElementIDs::MkTrackEntry:
case ElementIDs::MkAudio:
return new MasterElement(id, sizeLength, dataSize, offset);
case ElementIDs::MkTagName:
@ -81,17 +91,25 @@ EBML::Element *EBML::Element::factory(File &file)
case ElementIDs::MkTagLanguage:
case ElementIDs::MkAttachedFileMediaType:
case ElementIDs::MkCodecID:
return new Latin1StringElement(id, sizeLength, dataSize);
case ElementIDs::MkTagTargetTypeValue:
case ElementIDs::MkAttachedFileUID:
case ElementIDs::MkSeekPosition:
case ElementIDs::MkTimestampScale:
case ElementIDs::MkBitDepth:
case ElementIDs::MkChannels:
return new UIntElement(id, sizeLength, dataSize);
case ElementIDs::MkAttachedFileData:
case ElementIDs::MkSeekID:
return new BinaryElement(id, sizeLength, dataSize);
case ElementIDs::MkDuration:
case ElementIDs::MkSamplingFrequency:
return new FloatElement(id, sizeLength, dataSize);
case ElementIDs::MkSeekHead:
return new MkSeekHead(sizeLength, dataSize, offset);

View File

@ -98,6 +98,16 @@ namespace TagLib::EBML {
inline constexpr Element::Id MkCueCodecState = 0xEA;
inline constexpr Element::Id MkCueReference = 0xDB;
inline constexpr Element::Id MkCueRefTime = 0x96;
inline constexpr Element::Id MkInfo = 0x1549A966;
inline constexpr Element::Id MkTimestampScale = 0x2AD7B1;
inline constexpr Element::Id MkDuration = 0x4489;
inline constexpr Element::Id MkTracks = 0x1654AE6B;
inline constexpr Element::Id MkTrackEntry = 0xAE;
inline constexpr Element::Id MkCodecID = 0x86;
inline constexpr Element::Id MkAudio = 0xE1;
inline constexpr Element::Id MkSamplingFrequency = 0xB5;
inline constexpr Element::Id MkBitDepth = 0x6264;
inline constexpr Element::Id MkChannels = 0x9F;
}
}

View File

@ -0,0 +1,82 @@
/***************************************************************************
copyright : (C) 2025 by Urs Fleisch
email : ufleisch@users.sourceforge.net
***************************************************************************/
/***************************************************************************
* 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 "ebmlfloatelement.h"
#include "ebmlutils.h"
#include "tbytevector.h"
#include "tfile.h"
#include "tdebug.h"
using namespace TagLib;
double EBML::FloatElement::getValueAsDouble(double defaultValue) const
{
if(std::holds_alternative<double>(value)) {
return std::get<double>(value);
}
if(std::holds_alternative<float>(value)) {
return std::get<float>(value);
}
return defaultValue;
}
bool EBML::FloatElement::read(File &file)
{
ByteVector buffer = file.readBlock(dataSize);
if(buffer.size() != dataSize) {
debug("Failed to read EBML Float element");
return false;
}
if(dataSize == 0) {
value = std::monostate();
}
else if(dataSize == 4) {
value = buffer.toFloat32BE(0);
}
else if(dataSize == 8) {
value = buffer.toFloat64BE(0);
}
else {
debug("Invalid size for EBML Float element");
return false;
}
return true;
}
ByteVector EBML::FloatElement::render()
{
ByteVector data;
if(std::holds_alternative<double>(value)) {
data = ByteVector::fromFloat64BE(std::get<double>(value));
}
else if(std::holds_alternative<float>(value)) {
data = ByteVector::fromFloat32BE(std::get<float>(value));
}
ByteVector buffer = renderId();
buffer.append(renderVINT(data.size(), 0));
buffer.append(data);
return buffer;
}

View File

@ -0,0 +1,64 @@
/***************************************************************************
copyright : (C) 2025 by Urs Fleisch
email : ufleisch@users.sourceforge.net
***************************************************************************/
/***************************************************************************
* 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_EBMLFLOATELEMENT_H
#define TAGLIB_EBMLFLOATELEMENT_H
#ifndef DO_NOT_DOCUMENT
#include <variant>
#include "ebmlelement.h"
namespace TagLib {
class File;
namespace EBML {
class FloatElement : public Element
{
public:
using FloatVariantType = std::variant<std::monostate, float, double>;
FloatElement(Id id, int sizeLength, offset_t dataSize) :
Element(id, sizeLength, dataSize)
{
}
explicit FloatElement(Id id) :
FloatElement(id, 0, 0)
{
}
FloatVariantType getValue() const { return value; }
double getValueAsDouble(double defaultValue = 0.0) const;
void setValue(FloatVariantType val) { value = val; }
bool read(File &file) override;
ByteVector render() override;
private:
FloatVariantType value;
};
}
}
#endif
#endif

View File

@ -0,0 +1,53 @@
/***************************************************************************
copyright : (C) 2025 by Urs Fleisch
email : ufleisch@users.sourceforge.net
***************************************************************************/
/***************************************************************************
* 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 "ebmlmkinfo.h"
#include "ebmlstringelement.h"
#include "ebmluintelement.h"
#include "ebmlfloatelement.h"
#include "matroskaproperties.h"
using namespace TagLib;
void EBML::MkInfo::parse(Matroska::Properties *properties)
{
if(!properties)
return;
unsigned long long timestampScale = 1000000;
double duration = 0.0;
for(auto element : elements) {
Id id = element->getId();
if (id == ElementIDs::MkTimestampScale) {
timestampScale = static_cast<UIntElement *>(element)->getValue();
}
else if (id == ElementIDs::MkDuration) {
duration = static_cast<FloatElement *>(element)->getValueAsDouble();
}
}
properties->setLengthInMilliseconds(
static_cast<int>(duration * static_cast<double>(timestampScale) / 1000000.0));
}

View File

@ -0,0 +1,56 @@
/***************************************************************************
copyright : (C) 2025 by Urs Fleisch
email : ufleisch@users.sourceforge.net
***************************************************************************/
/***************************************************************************
* 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_EBMLMKINFO_H
#define TAGLIB_EBMLMKINFO_H
#ifndef DO_NOT_DOCUMENT
#include "ebmlmasterelement.h"
#include "ebmlutils.h"
#include "taglib.h"
namespace TagLib {
namespace Matroska {
class Properties;
}
namespace EBML {
class MkInfo : public MasterElement
{
public:
MkInfo(int sizeLength, offset_t dataSize, offset_t offset) :
MasterElement(ElementIDs::MkInfo, sizeLength, dataSize, offset)
{
}
MkInfo() :
MasterElement(ElementIDs::MkInfo, 0, 0, 0)
{
}
void parse(Matroska::Properties * properties);
};
}
}
#endif
#endif

View File

@ -25,9 +25,9 @@
using namespace TagLib;
Matroska::SeekHead *EBML::MkSeekHead::parse()
std::unique_ptr<Matroska::SeekHead> EBML::MkSeekHead::parse()
{
auto seekHead = new Matroska::SeekHead();
auto seekHead = std::make_unique<Matroska::SeekHead>();
seekHead->setOffset(offset);
seekHead->setSize(getSize() + padding);
@ -50,7 +50,7 @@ Matroska::SeekHead *EBML::MkSeekHead::parse()
if(entryId && offset)
seekHead->addEntry(entryId, offset);
else {
delete seekHead;
seekHead.reset();
return nullptr;
}
}

View File

@ -22,6 +22,8 @@
#include "ebmlmktags.h"
#include "ebmlmkattachments.h"
#include "ebmlmkseekhead.h"
#include "ebmlmkinfo.h"
#include "ebmlmktracks.h"
#include "ebmlutils.h"
#include "matroskafile.h"
#include "matroskatag.h"
@ -36,6 +38,8 @@ EBML::MkSegment::~MkSegment()
delete tags;
delete attachments;
delete seekHead;
delete info;
delete tracks;
}
bool EBML::MkSegment::read(File &file)
@ -52,6 +56,16 @@ bool EBML::MkSegment::read(File &file)
if(!seekHead->read(file))
return false;
}
else if(id == ElementIDs::MkInfo) {
info = static_cast<MkInfo *>(element);
if(!info->read(file))
return false;
}
else if(id == ElementIDs::MkTracks) {
tracks = static_cast<MkTracks *>(element);
if(!tracks->read(file))
return false;
}
else if(id == ElementIDs::MkTags) {
tags = static_cast<MkTags *>(element);
if(!tags->read(file))
@ -95,3 +109,17 @@ Matroska::Segment *EBML::MkSegment::parseSegment()
{
return new Matroska::Segment(sizeLength, dataSize, offset + idSize(id));
}
void EBML::MkSegment::parseInfo(Matroska::Properties *properties)
{
if(info) {
info->parse(properties);
}
}
void EBML::MkSegment::parseTracks(Matroska::Properties *properties)
{
if (tracks) {
tracks->parse(properties);
}
}

View File

@ -23,6 +23,8 @@
#ifndef DO_NOT_DOCUMENT
#include "ebmlmasterelement.h"
#include "ebmlmkinfo.h"
#include "ebmlmktracks.h"
#include "taglib.h"
namespace TagLib {
@ -49,11 +51,15 @@ namespace TagLib {
Matroska::Attachments *parseAttachments();
Matroska::SeekHead *parseSeekHead();
Matroska::Segment *parseSegment();
void parseInfo(Matroska::Properties *properties);
void parseTracks(Matroska::Properties *properties);
private:
MkTags *tags = nullptr;
MkAttachments *attachments = nullptr;
MkSeekHead *seekHead = nullptr;
MkInfo *info = nullptr;
MkTracks *tracks = nullptr;
};
}
}

View File

@ -0,0 +1,73 @@
/***************************************************************************
copyright : (C) 2025 by Urs Fleisch
email : ufleisch@users.sourceforge.net
***************************************************************************/
/***************************************************************************
* 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 "ebmlmktracks.h"
#include "ebmlstringelement.h"
#include "ebmluintelement.h"
#include "ebmlfloatelement.h"
#include "matroskaproperties.h"
using namespace TagLib;
void EBML::MkTracks::parse(Matroska::Properties *properties)
{
if(!properties)
return;
for(auto element : elements) {
if(element->getId() != ElementIDs::MkTrackEntry)
continue;
String codecId;
double samplingFrequency = 0.0;
unsigned long long bitDepth = 0;
unsigned long long channels = 0;
auto trackEntry = static_cast<MasterElement *>(element);
for(auto trackEntryChild : *trackEntry) {
Id trackEntryChildId = trackEntryChild->getId();
if(trackEntryChildId == ElementIDs::MkCodecID)
codecId = static_cast<Latin1StringElement *>(trackEntryChild)->getValue();
else if(trackEntryChildId == ElementIDs::MkAudio) {
auto audio = static_cast<MasterElement *>(trackEntryChild);
for(auto audioChild : *audio) {
Id audioChildId = audioChild->getId();
if(audioChildId == ElementIDs::MkSamplingFrequency)
samplingFrequency = static_cast<FloatElement *>(audioChild)->getValueAsDouble();
else if(audioChildId == ElementIDs::MkBitDepth)
bitDepth = static_cast<UIntElement *>(audioChild)->getValue();
else if(audioChildId == ElementIDs::MkChannels)
channels = static_cast<UIntElement *>(audioChild)->getValue();
}
}
}
if(bitDepth || channels) {
properties->setSampleRate(static_cast<int>(samplingFrequency));
properties->setBitsPerSample(static_cast<int>(bitDepth));
properties->setChannels(static_cast<int>(channels));
properties->setCodecName(codecId);
return;
}
}
}

View File

@ -0,0 +1,56 @@
/***************************************************************************
copyright : (C) 2025 by Urs Fleisch
email : ufleisch@users.sourceforge.net
***************************************************************************/
/***************************************************************************
* 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_EBMLMKTRACKS_H
#define TAGLIB_EBMLMKTRACKS_H
#ifndef DO_NOT_DOCUMENT
#include "ebmlmasterelement.h"
#include "ebmlutils.h"
#include "taglib.h"
namespace TagLib {
namespace Matroska {
class Properties;
}
namespace EBML {
class MkTracks : public MasterElement
{
public:
MkTracks(int sizeLength, offset_t dataSize, offset_t offset) :
MasterElement(ElementIDs::MkTracks, sizeLength, dataSize, offset)
{
}
MkTracks() :
MasterElement(ElementIDs::MkTracks, 0, 0, 0)
{
}
void parse(Matroska::Properties *properties);
};
}
}
#endif
#endif

View File

@ -44,6 +44,7 @@ public:
delete tag;
delete attachments;
delete seekHead;
delete segment;
}
FilePrivate(const FilePrivate &) = delete;
@ -52,6 +53,7 @@ public:
Attachments *attachments = nullptr;
SeekHead *seekHead = nullptr;
Segment *segment = nullptr;
std::unique_ptr<Properties> properties;
};
////////////////////////////////////////////////////////////////////////////////
@ -96,6 +98,11 @@ Matroska::File::File(IOStream *stream, bool readProperties,
Matroska::File::~File() = default;
AudioProperties *Matroska::File::audioProperties() const
{
return d->properties.get();
}
Tag *Matroska::File::tag() const
{
return tag(true);
@ -123,7 +130,7 @@ Matroska::Attachments *Matroska::File::attachments(bool create) const
}
}
void Matroska::File::read(bool, Properties::ReadStyle)
void Matroska::File::read(bool readProperties, Properties::ReadStyle)
{
offset_t fileLength = length();
@ -162,6 +169,12 @@ void Matroska::File::read(bool, Properties::ReadStyle)
d->attachments = segment->parseAttachments();
setValid(true);
if(readProperties) {
d->properties = std::make_unique<Properties>(this);
segment->parseInfo(d->properties.get());
segment->parseTracks(d->properties.get());
}
}
bool Matroska::File::save()

View File

@ -40,7 +40,7 @@ namespace TagLib::Matroska {
~File() override;
File(const File &) = delete;
File &operator=(const File &) = delete;
AudioProperties *audioProperties() const override { return nullptr; }
AudioProperties *audioProperties() const override;
TagLib::Tag *tag() const override;
Attachments *attachments(bool create = false) const;
Tag *tag(bool create) const;
@ -60,6 +60,7 @@ namespace TagLib::Matroska {
private:
void read(bool readProperties, Properties::ReadStyle readStyle);
class FilePrivate;
friend class Properties;
TAGLIB_MSVC_SUPPRESS_WARNING_NEEDS_TO_HAVE_DLL_INTERFACE
std::unique_ptr<FilePrivate> d;
};

View File

@ -25,23 +25,36 @@
#include "matroskaproperties.h"
#include "matroskafile.h"
using namespace TagLib;
class Matroska::Properties::PropertiesPrivate
{
public:
explicit PropertiesPrivate(File *file) : file(file) {}
~PropertiesPrivate() = default;
PropertiesPrivate(const PropertiesPrivate &) = delete;
PropertiesPrivate &operator=(const PropertiesPrivate &) = delete;
File *file;
String codecName;
int length { 0 };
int bitrate { 0 };
int bitrate { -1 };
int sampleRate { 0 };
int bitsPerSample { 0 };
int channels { 0 };
int bitsPerSample { 0 };
};
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
Matroska::Properties::Properties(File *file, ReadStyle style) :
AudioProperties(style),
d(std::make_unique<PropertiesPrivate>())
d(std::make_unique<PropertiesPrivate>(file))
{
read(file);
}
Matroska::Properties::~Properties() = default;
@ -53,6 +66,9 @@ int Matroska::Properties::lengthInMilliseconds() const
int Matroska::Properties::bitrate() const
{
if (d->bitrate == -1) {
d->bitrate = d->length != 0 ? static_cast<int>(d->file->length() * 8 / d->length) : 0;
}
return d->bitrate;
}
@ -66,11 +82,46 @@ int Matroska::Properties::channels() const
return d->channels;
}
int Matroska::Properties::bitsPerSample() const
{
return d->bitsPerSample;
}
String Matroska::Properties::codecName() const
{
return d->codecName;
}
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////
void Matroska::Properties::read(File *)
void Matroska::Properties::setLengthInMilliseconds(int length)
{
// TODO implement.
d->length = length;
}
void Matroska::Properties::setBitrate(int bitrate)
{
d->bitrate = bitrate;
}
void Matroska::Properties::setSampleRate(int sampleRate)
{
d->sampleRate = sampleRate;
}
void Matroska::Properties::setChannels(int channels)
{
d->channels = channels;
}
void Matroska::Properties::setBitsPerSample(int bitsPerSample)
{
d->bitsPerSample = bitsPerSample;
}
void Matroska::Properties::setCodecName(const String &codecName)
{
d->codecName = codecName;
}

View File

@ -1,3 +1,8 @@
/***************************************************************************
copyright : (C) 2025 by Urs Fleisch
email : ufleisch@users.sourceforge.net
***************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
@ -24,15 +29,25 @@
#include "taglib_export.h"
#include "audioproperties.h"
namespace TagLib::EBML {
class MkTracks;
class MkInfo;
}
namespace TagLib::Matroska {
class File;
//! An implementation of Matroska audio properties
class TAGLIB_EXPORT Properties : public AudioProperties
{
public:
/*!
* Creates an instance of Matroska::Properties.
*/
explicit Properties(File *file, ReadStyle style = Average);
/*!
* Destroys this Matroska::Properties instance.
*/
~Properties() override;
Properties(const Properties &) = delete;
@ -60,10 +75,29 @@ namespace TagLib::Matroska {
*/
int channels() const override;
private:
void read(File *file);
/*!
* Returns the number of bits per audio sample.
*/
int bitsPerSample() const;
/*!
* Returns the concrete codec name, for example "A_MPEG/L3"
* used in the file if available, otherwise an empty string.
*/
String codecName() const;
private:
class PropertiesPrivate;
friend class EBML::MkInfo;
friend class EBML::MkTracks;
void setLengthInMilliseconds(int length);
void setBitrate(int bitrate);
void setSampleRate(int sampleRate);
void setChannels(int channels);
void setBitsPerSample(int bitsPerSample);
void setCodecName(const String &codecName);
TAGLIB_MSVC_SUPPRESS_WARNING_NEEDS_TO_HAVE_DLL_INTERFACE
std::unique_ptr<PropertiesPrivate> d;
};