mirror of
https://github.com/taglib/taglib.git
synced 2026-02-08 00:10:15 -05:00
Implement Matroska audio properties
This commit is contained in:
@ -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
|
||||
)
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
82
taglib/matroska/ebml/ebmlfloatelement.cpp
Normal file
82
taglib/matroska/ebml/ebmlfloatelement.cpp
Normal 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;
|
||||
}
|
||||
64
taglib/matroska/ebml/ebmlfloatelement.h
Normal file
64
taglib/matroska/ebml/ebmlfloatelement.h
Normal 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
|
||||
53
taglib/matroska/ebml/ebmlmkinfo.cpp
Normal file
53
taglib/matroska/ebml/ebmlmkinfo.cpp
Normal 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));
|
||||
}
|
||||
56
taglib/matroska/ebml/ebmlmkinfo.h
Normal file
56
taglib/matroska/ebml/ebmlmkinfo.h
Normal 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
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
73
taglib/matroska/ebml/ebmlmktracks.cpp
Normal file
73
taglib/matroska/ebml/ebmlmktracks.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
56
taglib/matroska/ebml/ebmlmktracks.h
Normal file
56
taglib/matroska/ebml/ebmlmktracks.h
Normal 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
|
||||
@ -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()
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user