Skip to content

Commit cfade6d

Browse files
committed
Implement Matroska audio properties
1 parent f7ab162 commit cfade6d

16 files changed

Lines changed: 565 additions & 14 deletions

taglib/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,9 +245,12 @@ if(WITH_MATROSKA)
245245
matroska/ebml/ebmlmkcues.h
246246
matroska/ebml/ebmlmkseekhead.h
247247
matroska/ebml/ebmlmksegment.h
248+
matroska/ebml/ebmlmkinfo.h
249+
matroska/ebml/ebmlmktracks.h
248250
matroska/ebml/ebmlmktags.h
249251
matroska/ebml/ebmlstringelement.h
250252
matroska/ebml/ebmluintelement.h
253+
matroska/ebml/ebmlfloatelement.h
251254
matroska/ebml/ebmlutils.h
252255
matroska/ebml/ebmlvoidelement.h
253256
)
@@ -464,9 +467,12 @@ if(WITH_MATROSKA)
464467
matroska/ebml/ebmlmkcues.cpp
465468
matroska/ebml/ebmlmkseekhead.cpp
466469
matroska/ebml/ebmlmksegment.cpp
470+
matroska/ebml/ebmlmkinfo.cpp
471+
matroska/ebml/ebmlmktracks.cpp
467472
matroska/ebml/ebmlmktags.cpp
468473
matroska/ebml/ebmlstringelement.cpp
469474
matroska/ebml/ebmluintelement.cpp
475+
matroska/ebml/ebmlfloatelement.cpp
470476
matroska/ebml/ebmlutils.cpp
471477
matroska/ebml/ebmlvoidelement.cpp
472478
)

taglib/matroska/ebml/ebmlelement.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@
2222
#include "ebmlvoidelement.h"
2323
#include "ebmlmasterelement.h"
2424
#include "ebmlbinaryelement.h"
25+
#include "ebmlfloatelement.h"
2526
#include "ebmlmkseekhead.h"
2627
#include "ebmlmksegment.h"
2728
#include "ebmlmktags.h"
2829
#include "ebmlmkattachments.h"
30+
#include "ebmlmktracks.h"
2931
#include "ebmlstringelement.h"
3032
#include "ebmluintelement.h"
3133
#include "ebmlutils.h"
@@ -60,6 +62,12 @@ EBML::Element *EBML::Element::factory(File &file)
6062
case ElementIDs::MkSegment:
6163
return new MkSegment(sizeLength, dataSize, offset);
6264

65+
case ElementIDs::MkInfo:
66+
return new MkInfo(sizeLength, dataSize, offset);
67+
68+
case ElementIDs::MkTracks:
69+
return new MkTracks(sizeLength, dataSize, offset);
70+
6371
case ElementIDs::MkTags:
6472
return new MkTags(sizeLength, dataSize, offset);
6573

@@ -71,6 +79,8 @@ EBML::Element *EBML::Element::factory(File &file)
7179
case ElementIDs::MkSimpleTag:
7280
case ElementIDs::MkAttachedFile:
7381
case ElementIDs::MkSeek:
82+
case ElementIDs::MkTrackEntry:
83+
case ElementIDs::MkAudio:
7484
return new MasterElement(id, sizeLength, dataSize, offset);
7585

7686
case ElementIDs::MkTagName:
@@ -81,17 +91,25 @@ EBML::Element *EBML::Element::factory(File &file)
8191

8292
case ElementIDs::MkTagLanguage:
8393
case ElementIDs::MkAttachedFileMediaType:
94+
case ElementIDs::MkCodecID:
8495
return new Latin1StringElement(id, sizeLength, dataSize);
8596

8697
case ElementIDs::MkTagTargetTypeValue:
8798
case ElementIDs::MkAttachedFileUID:
8899
case ElementIDs::MkSeekPosition:
100+
case ElementIDs::MkTimestampScale:
101+
case ElementIDs::MkBitDepth:
102+
case ElementIDs::MkChannels:
89103
return new UIntElement(id, sizeLength, dataSize);
90104

91105
case ElementIDs::MkAttachedFileData:
92106
case ElementIDs::MkSeekID:
93107
return new BinaryElement(id, sizeLength, dataSize);
94108

109+
case ElementIDs::MkDuration:
110+
case ElementIDs::MkSamplingFrequency:
111+
return new FloatElement(id, sizeLength, dataSize);
112+
95113
case ElementIDs::MkSeekHead:
96114
return new MkSeekHead(sizeLength, dataSize, offset);
97115

taglib/matroska/ebml/ebmlelement.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,16 @@ namespace TagLib::EBML {
9898
inline constexpr Element::Id MkCueCodecState = 0xEA;
9999
inline constexpr Element::Id MkCueReference = 0xDB;
100100
inline constexpr Element::Id MkCueRefTime = 0x96;
101+
inline constexpr Element::Id MkInfo = 0x1549A966;
102+
inline constexpr Element::Id MkTimestampScale = 0x2AD7B1;
103+
inline constexpr Element::Id MkDuration = 0x4489;
104+
inline constexpr Element::Id MkTracks = 0x1654AE6B;
105+
inline constexpr Element::Id MkTrackEntry = 0xAE;
106+
inline constexpr Element::Id MkCodecID = 0x86;
107+
inline constexpr Element::Id MkAudio = 0xE1;
108+
inline constexpr Element::Id MkSamplingFrequency = 0xB5;
109+
inline constexpr Element::Id MkBitDepth = 0x6264;
110+
inline constexpr Element::Id MkChannels = 0x9F;
101111
}
102112
}
103113

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/***************************************************************************
2+
copyright : (C) 2025 by Urs Fleisch
3+
email : ufleisch@users.sourceforge.net
4+
***************************************************************************/
5+
6+
/***************************************************************************
7+
* This library is free software; you can redistribute it and/or modify *
8+
* it under the terms of the GNU Lesser General Public License version *
9+
* 2.1 as published by the Free Software Foundation. *
10+
* *
11+
* This library is distributed in the hope that it will be useful, but *
12+
* WITHOUT ANY WARRANTY; without even the implied warranty of *
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14+
* Lesser General Public License for more details. *
15+
* *
16+
* You should have received a copy of the GNU Lesser General Public *
17+
* License along with this library; if not, write to the Free Software *
18+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
19+
* 02110-1301 USA *
20+
* *
21+
* Alternatively, this file is available under the Mozilla Public *
22+
* License Version 1.1. You may obtain a copy of the License at *
23+
* http://www.mozilla.org/MPL/ *
24+
***************************************************************************/
25+
26+
#include "ebmlfloatelement.h"
27+
#include "ebmlutils.h"
28+
#include "tbytevector.h"
29+
#include "tfile.h"
30+
#include "tdebug.h"
31+
32+
using namespace TagLib;
33+
34+
double EBML::FloatElement::getValueAsDouble(double defaultValue) const
35+
{
36+
if(std::holds_alternative<double>(value)) {
37+
return std::get<double>(value);
38+
}
39+
if(std::holds_alternative<float>(value)) {
40+
return std::get<float>(value);
41+
}
42+
return defaultValue;
43+
}
44+
45+
bool EBML::FloatElement::read(File &file)
46+
{
47+
ByteVector buffer = file.readBlock(dataSize);
48+
if(buffer.size() != dataSize) {
49+
debug("Failed to read EBML Float element");
50+
return false;
51+
}
52+
53+
if(dataSize == 0) {
54+
value = std::monostate();
55+
}
56+
else if(dataSize == 4) {
57+
value = buffer.toFloat32BE(0);
58+
}
59+
else if(dataSize == 8) {
60+
value = buffer.toFloat64BE(0);
61+
}
62+
else {
63+
debug("Invalid size for EBML Float element");
64+
return false;
65+
}
66+
return true;
67+
}
68+
69+
ByteVector EBML::FloatElement::render()
70+
{
71+
ByteVector data;
72+
if(std::holds_alternative<double>(value)) {
73+
data = ByteVector::fromFloat64BE(std::get<double>(value));
74+
}
75+
else if(std::holds_alternative<float>(value)) {
76+
data = ByteVector::fromFloat32BE(std::get<float>(value));
77+
}
78+
ByteVector buffer = renderId();
79+
buffer.append(renderVINT(data.size(), 0));
80+
buffer.append(data);
81+
return buffer;
82+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/***************************************************************************
2+
copyright : (C) 2025 by Urs Fleisch
3+
email : ufleisch@users.sourceforge.net
4+
***************************************************************************/
5+
6+
/***************************************************************************
7+
* This library is free software; you can redistribute it and/or modify *
8+
* it under the terms of the GNU Lesser General Public License version *
9+
* 2.1 as published by the Free Software Foundation. *
10+
* *
11+
* This library is distributed in the hope that it will be useful, but *
12+
* WITHOUT ANY WARRANTY; without even the implied warranty of *
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14+
* Lesser General Public License for more details. *
15+
* *
16+
* You should have received a copy of the GNU Lesser General Public *
17+
* License along with this library; if not, write to the Free Software *
18+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
19+
* 02110-1301 USA *
20+
* *
21+
* Alternatively, this file is available under the Mozilla Public *
22+
* License Version 1.1. You may obtain a copy of the License at *
23+
* http://www.mozilla.org/MPL/ *
24+
***************************************************************************/
25+
26+
#ifndef TAGLIB_EBMLFLOATELEMENT_H
27+
#define TAGLIB_EBMLFLOATELEMENT_H
28+
#ifndef DO_NOT_DOCUMENT
29+
30+
#include <variant>
31+
#include "ebmlelement.h"
32+
33+
namespace TagLib {
34+
class File;
35+
36+
namespace EBML {
37+
class FloatElement : public Element
38+
{
39+
public:
40+
using FloatVariantType = std::variant<std::monostate, float, double>;
41+
42+
FloatElement(Id id, int sizeLength, offset_t dataSize) :
43+
Element(id, sizeLength, dataSize)
44+
{
45+
}
46+
47+
explicit FloatElement(Id id) :
48+
FloatElement(id, 0, 0)
49+
{
50+
}
51+
FloatVariantType getValue() const { return value; }
52+
double getValueAsDouble(double defaultValue = 0.0) const;
53+
void setValue(FloatVariantType val) { value = val; }
54+
bool read(File &file) override;
55+
ByteVector render() override;
56+
57+
private:
58+
FloatVariantType value;
59+
};
60+
}
61+
}
62+
63+
#endif
64+
#endif
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/***************************************************************************
2+
copyright : (C) 2025 by Urs Fleisch
3+
email : ufleisch@users.sourceforge.net
4+
***************************************************************************/
5+
6+
/***************************************************************************
7+
* This library is free software; you can redistribute it and/or modify *
8+
* it under the terms of the GNU Lesser General Public License version *
9+
* 2.1 as published by the Free Software Foundation. *
10+
* *
11+
* This library is distributed in the hope that it will be useful, but *
12+
* WITHOUT ANY WARRANTY; without even the implied warranty of *
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14+
* Lesser General Public License for more details. *
15+
* *
16+
* You should have received a copy of the GNU Lesser General Public *
17+
* License along with this library; if not, write to the Free Software *
18+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
19+
* 02110-1301 USA *
20+
* *
21+
* Alternatively, this file is available under the Mozilla Public *
22+
* License Version 1.1. You may obtain a copy of the License at *
23+
* http://www.mozilla.org/MPL/ *
24+
***************************************************************************/
25+
26+
#include "ebmlmkinfo.h"
27+
#include "ebmlstringelement.h"
28+
#include "ebmluintelement.h"
29+
#include "ebmlfloatelement.h"
30+
#include "matroskaproperties.h"
31+
32+
using namespace TagLib;
33+
34+
void EBML::MkInfo::parse(Matroska::Properties *properties)
35+
{
36+
if(!properties)
37+
return;
38+
39+
unsigned long long timestampScale = 1000000;
40+
double duration = 0.0;
41+
for(auto element : elements) {
42+
Id id = element->getId();
43+
if (id == ElementIDs::MkTimestampScale) {
44+
timestampScale = static_cast<UIntElement *>(element)->getValue();
45+
}
46+
else if (id == ElementIDs::MkDuration) {
47+
duration = static_cast<FloatElement *>(element)->getValueAsDouble();
48+
}
49+
}
50+
51+
properties->setLengthInMilliseconds(
52+
static_cast<int>(duration * static_cast<double>(timestampScale) / 1000000.0));
53+
}

taglib/matroska/ebml/ebmlmkinfo.h

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/***************************************************************************
2+
copyright : (C) 2025 by Urs Fleisch
3+
email : ufleisch@users.sourceforge.net
4+
***************************************************************************/
5+
6+
/***************************************************************************
7+
* This library is free software; you can redistribute it and/or modify *
8+
* it under the terms of the GNU Lesser General Public License version *
9+
* 2.1 as published by the Free Software Foundation. *
10+
* *
11+
* This library is distributed in the hope that it will be useful, but *
12+
* WITHOUT ANY WARRANTY; without even the implied warranty of *
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14+
* Lesser General Public License for more details. *
15+
* *
16+
* You should have received a copy of the GNU Lesser General Public *
17+
* License along with this library; if not, write to the Free Software *
18+
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
19+
* 02110-1301 USA *
20+
* *
21+
* Alternatively, this file is available under the Mozilla Public *
22+
* License Version 1.1. You may obtain a copy of the License at *
23+
* http://www.mozilla.org/MPL/ *
24+
***************************************************************************/
25+
26+
#ifndef TAGLIB_EBMLMKINFO_H
27+
#define TAGLIB_EBMLMKINFO_H
28+
#ifndef DO_NOT_DOCUMENT
29+
30+
#include "ebmlmasterelement.h"
31+
#include "ebmlutils.h"
32+
#include "taglib.h"
33+
34+
namespace TagLib {
35+
namespace Matroska {
36+
class Properties;
37+
}
38+
namespace EBML {
39+
class MkInfo : public MasterElement
40+
{
41+
public:
42+
MkInfo(int sizeLength, offset_t dataSize, offset_t offset) :
43+
MasterElement(ElementIDs::MkInfo, sizeLength, dataSize, offset)
44+
{
45+
}
46+
MkInfo() :
47+
MasterElement(ElementIDs::MkInfo, 0, 0, 0)
48+
{
49+
}
50+
void parse(Matroska::Properties * properties);
51+
};
52+
}
53+
}
54+
55+
#endif
56+
#endif

taglib/matroska/ebml/ebmlmkseekhead.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@
2525

2626
using namespace TagLib;
2727

28-
Matroska::SeekHead *EBML::MkSeekHead::parse()
28+
std::unique_ptr<Matroska::SeekHead> EBML::MkSeekHead::parse()
2929
{
30-
auto seekHead = new Matroska::SeekHead();
30+
auto seekHead = std::make_unique<Matroska::SeekHead>();
3131
seekHead->setOffset(offset);
3232
seekHead->setSize(getSize() + padding);
3333

@@ -50,7 +50,7 @@ Matroska::SeekHead *EBML::MkSeekHead::parse()
5050
if(entryId && offset)
5151
seekHead->addEntry(entryId, offset);
5252
else {
53-
delete seekHead;
53+
seekHead.reset();
5454
return nullptr;
5555
}
5656
}

0 commit comments

Comments
 (0)