Tag Parser: tests/overallmp3.cpp Source File

Tag Parser 12.5.2 C++ library for reading and writing MP4 (iTunes), ID3, Vorbis, Opus, FLAC and Matroska tags

Loading...
Searching...
No Matches
overallmp3.cpp
Go to the documentation of this file.
1#include "./helper.h"
2#include "./overall.h"
3
4#include "../abstracttrack.h"
5#include "../id3/id3v1tag.h"
6#include "../id3/id3v2tag.h"
7#include "../mpegaudio/mpegaudioframe.h"
8
9#include <regex>
10
11 namespace Mp3TestFlags {
12 enum TestFlag {
13 ForceRewring = 0x1,
14 Id3v2AndId3v1 = 0x2,
15 PaddingConstraints = 0x4,
16 Id3v1Only = 0x8,
17 RemoveTag = Id3v2AndId3v1 & Id3v1Only,
18 UseId3v24 = 0x10,
19};
20}
21
25void OverallTests::checkMp3Testfile1()
26{
27 CPPUNIT_ASSERT_EQUAL(ContainerFormat::MpegAudioFrames, m_fileInfo.containerFormat());
28 const auto tracks = m_fileInfo.tracks();
29 CPPUNIT_ASSERT_EQUAL(1_st, tracks.size());
30 for (const auto &track : tracks) {
31 CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
32 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Mpeg1Audio, track->format().general);
33 CPPUNIT_ASSERT_EQUAL(static_cast<unsigned char>(SubFormats::Mpeg1Layer3), track->format().sub);
34 CPPUNIT_ASSERT_EQUAL(static_cast<std::uint16_t>(2), track->channelCount());
35 CPPUNIT_ASSERT_EQUAL(static_cast<std::uint8_t>(MpegChannelMode::JointStereo), track->channelConfig());
36 CPPUNIT_ASSERT_EQUAL(44100u, track->samplingFrequency());
37 CPPUNIT_ASSERT_EQUAL(3, track->duration().seconds());
38 }
39 const auto tags = m_fileInfo.tags();
40 switch (m_tagStatus) {
41 case TagStatus::Original:
42 CPPUNIT_ASSERT(m_fileInfo.id3v1Tag());
43 CPPUNIT_ASSERT_EQUAL(1_st, m_fileInfo.id3v2Tags().size());
44 CPPUNIT_ASSERT_EQUAL(2_st, tags.size());
45 for (const auto &tag : tags) {
46 CPPUNIT_ASSERT_EQUAL(4, tag->value(KnownField::TrackPosition).toPositionInSet().position());
47 CPPUNIT_ASSERT_EQUAL("1984"s, tag->value(KnownField::RecordDate).toString());
48 switch (tag->type()) {
49 case TagType::Id3v1Tag:
50 CPPUNIT_ASSERT_EQUAL("Cohesion"s, tag->value(KnownField::Title).toString());
51 CPPUNIT_ASSERT_EQUAL("Minutemen"s, tag->value(KnownField::Artist).toString());
52 CPPUNIT_ASSERT_EQUAL("Double Nickels On The Dime"s, tag->value(KnownField::Album).toString());
53 CPPUNIT_ASSERT_EQUAL("Punk Rock"s, tag->value(KnownField::Genre).toString());
54 CPPUNIT_ASSERT_EQUAL("ExactAudioCopy v0.95b4"s, tag->value(KnownField::Comment).toString());
55 break;
56 case TagType::Id3v2Tag:
57 CPPUNIT_ASSERT_EQUAL(TagTextEncoding::Utf16LittleEndian, tag->value(KnownField::Title).dataEncoding());
58 CPPUNIT_ASSERT_EQUAL(u"Cohesion"s, tag->value(KnownField::Title).toWString());
59 CPPUNIT_ASSERT_EQUAL("Cohesion"s, tag->value(KnownField::Title).toString(TagTextEncoding::Utf8));
60 CPPUNIT_ASSERT_EQUAL(u"Minutemen"s, tag->value(KnownField::Artist).toWString());
61 CPPUNIT_ASSERT_EQUAL("Minutemen"s, tag->value(KnownField::Artist).toString(TagTextEncoding::Utf8));
62 CPPUNIT_ASSERT_EQUAL(u"Double Nickels On The Dime"s, tag->value(KnownField::Album).toWString());
63 CPPUNIT_ASSERT_EQUAL("Double Nickels On The Dime"s, tag->value(KnownField::Album).toString(TagTextEncoding::Utf8));
64 CPPUNIT_ASSERT_EQUAL(u"Punk Rock"s, tag->value(KnownField::Genre).toWString());
65 CPPUNIT_ASSERT_EQUAL("Punk Rock"s, tag->value(KnownField::Genre).toString(TagTextEncoding::Utf8));
66 CPPUNIT_ASSERT_EQUAL(u"ExactAudioCopy v0.95b4"s, tag->value(KnownField::Comment).toWString());
67 CPPUNIT_ASSERT_EQUAL("ExactAudioCopy v0.95b4"s, tag->value(KnownField::Comment).toString(TagTextEncoding::Utf8));
68 CPPUNIT_ASSERT_EQUAL(43, tag->value(KnownField::TrackPosition).toPositionInSet().total());
69 CPPUNIT_ASSERT(tag->value(KnownField::Length).toTimeSpan().isNull());
70 CPPUNIT_ASSERT(tag->value(KnownField::Lyricist).isEmpty());
71 break;
72 default:;
73 }
74 }
75 break;
76 case TagStatus::TestMetaDataPresent:
77 checkMp3TestMetaData();
78 break;
79 case TagStatus::Removed:
80 CPPUNIT_ASSERT_EQUAL(0_st, tracks.size());
81 }
82
83 auto warningAboutEncoding = false;
84 for (auto &msg : m_diag) {
85 if (msg.message() == "The used encoding is unlikely to be supported by other software.") {
86 CPPUNIT_ASSERT_EQUAL(DiagLevel::Warning, msg.level());
87 warningAboutEncoding = true;
88 msg = DiagMessage(DiagLevel::Information, string(), string());
89 }
90 }
91 const auto encodingWarningExpected
92 = m_tagStatus == TagStatus::TestMetaDataPresent && (m_mode & Mp3TestFlags::Id3v1Only || m_mode & Mp3TestFlags::Id3v2AndId3v1);
93 CPPUNIT_ASSERT_EQUAL(encodingWarningExpected, warningAboutEncoding);
94 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Information);
95}
96
100void OverallTests::checkMp3Testfile2()
101{
102 CPPUNIT_ASSERT_EQUAL(ContainerFormat::MpegAudioFrames, m_fileInfo.containerFormat());
103 const auto tracks = m_fileInfo.tracks();
104 CPPUNIT_ASSERT_EQUAL(1_st, tracks.size());
105 for (const auto &track : tracks) {
106 CPPUNIT_ASSERT_EQUAL(MediaType::Audio, track->mediaType());
107 CPPUNIT_ASSERT_EQUAL(GeneralMediaFormat::Mpeg1Audio, track->format().general);
108 CPPUNIT_ASSERT_EQUAL(static_cast<unsigned char>(SubFormats::Mpeg1Layer3), track->format().sub);
109 CPPUNIT_ASSERT_EQUAL(static_cast<std::uint16_t>(2), track->channelCount());
110 CPPUNIT_ASSERT_EQUAL(static_cast<std::uint8_t>(MpegChannelMode::Stereo), track->channelConfig());
111 CPPUNIT_ASSERT_EQUAL(44100u, track->samplingFrequency());
112 CPPUNIT_ASSERT_EQUAL(20, track->duration().seconds());
113 }
114 const auto tags = m_fileInfo.tags();
115 const bool expectId3v24 = m_tagStatus == TagStatus::Original || m_mode & Mp3TestFlags::UseId3v24;
116 switch (m_tagStatus) {
117 case TagStatus::Original:
118 case TagStatus::TestMetaDataPresent:
119 CPPUNIT_ASSERT(!m_fileInfo.id3v1Tag());
120 CPPUNIT_ASSERT_EQUAL(1_st, m_fileInfo.id3v2Tags().size());
121 CPPUNIT_ASSERT_EQUAL(1_st, tags.size());
122 for (const auto &tag : tags) {
123 if (tag->type() != TagType::Id3v2Tag) {
124 CPPUNIT_FAIL(argsToString("no ", tag->typeName(), " tag expected"));
125 }
126 const auto *const id3v2Tag = static_cast<const Id3v2Tag *>(tag);
127
128 // check values as usual
129 CPPUNIT_ASSERT_EQUAL(expectId3v24 ? 4 : 3, static_cast<int>(id3v2Tag->majorVersion()));
130 CPPUNIT_ASSERT_EQUAL(
131 expectId3v24 ? TagTextEncoding::Utf8 : TagTextEncoding::Utf16LittleEndian, tag->value(KnownField::Title).dataEncoding());
132 CPPUNIT_ASSERT_EQUAL("Infinite (Original Mix)"s, tag->value(KnownField::Title).toString(TagTextEncoding::Utf8));
133 CPPUNIT_ASSERT_EQUAL("B-Front"s, tag->value(KnownField::Artist).toString(TagTextEncoding::Utf8));
134 CPPUNIT_ASSERT_EQUAL("Infinite"s, tag->value(KnownField::Album).toString(TagTextEncoding::Utf8));
135 CPPUNIT_ASSERT_EQUAL(m_tagStatus == TagStatus::TestMetaDataPresent ? "Test"s : "Hardstyle"s,
136 tag->value(KnownField::Genre).toString(TagTextEncoding::Utf8));
137 CPPUNIT_ASSERT_EQUAL("Lavf57.83.100"s, tag->value(KnownField::EncoderSettings).toString(TagTextEncoding::Utf8));
138 CPPUNIT_ASSERT_EQUAL("Roughstate"s, tag->value(KnownField::Publisher).toString(TagTextEncoding::Utf8));
139 CPPUNIT_ASSERT_EQUAL("2017"s, tag->value(KnownField::RecordDate).toString(TagTextEncoding::Utf8));
140 CPPUNIT_ASSERT_EQUAL(1, tag->value(KnownField::TrackPosition).toPositionInSet().position());
141 CPPUNIT_ASSERT(tag->value(KnownField::Length).toTimeSpan().isNull());
142 CPPUNIT_ASSERT(tag->value(KnownField::Lyricist).isEmpty());
143
144 // check additional text frame values
145 const auto &fields = id3v2Tag->fields();
146 auto genreFields = fields.equal_range(Id3v2FrameIds::lGenre);
147 CPPUNIT_ASSERT_MESSAGE("genre field present"s, genreFields.first != genreFields.second);
148 const auto &genreField = genreFields.first->second;
149 const auto &additionalValues = genreField.additionalValues();
150 if (m_tagStatus == TagStatus::TestMetaDataPresent) {
151 CPPUNIT_ASSERT_EQUAL("Test"s, tag->value(KnownField::Genre).toString(TagTextEncoding::Utf8));
152 CPPUNIT_ASSERT_EQUAL(1_st, additionalValues.size());
153 CPPUNIT_ASSERT_EQUAL("Example"s, additionalValues[0].toString(TagTextEncoding::Utf8));
154 } else {
155 CPPUNIT_ASSERT_EQUAL("Hardstyle"s, tag->value(KnownField::Genre).toString(TagTextEncoding::Utf8));
156 CPPUNIT_ASSERT_EQUAL(3_st, additionalValues.size());
157 CPPUNIT_ASSERT_EQUAL("Test"s, additionalValues[0].toString(TagTextEncoding::Utf8));
158 CPPUNIT_ASSERT_EQUAL("Example"s, additionalValues[1].toString(TagTextEncoding::Utf8));
159 CPPUNIT_ASSERT_EQUAL("Hard Dance"s, additionalValues[2].toString(TagTextEncoding::Utf8));
160 }
161 CPPUNIT_ASSERT_MESSAGE("exactly one genre field present"s, ++genreFields.first == genreFields.second);
162
163 // check whether additional text frame values are returned correctly by values()
164 const auto artists = id3v2Tag->values(KnownField::Artist);
165 CPPUNIT_ASSERT_EQUAL(m_tagStatus == TagStatus::TestMetaDataPresent ? 3_st : 2_st, artists.size());
166 CPPUNIT_ASSERT_EQUAL("B-Front"s, artists[0]->toString(TagTextEncoding::Utf8));
167 CPPUNIT_ASSERT_EQUAL("Second Artist Example"s, artists[1]->toString(TagTextEncoding::Utf8));
168 if (m_tagStatus == TagStatus::TestMetaDataPresent) {
169 CPPUNIT_ASSERT_EQUAL("3rd Artist Example"s, artists[2]->toString(TagTextEncoding::Utf8));
170 }
171
172 const auto genres = id3v2Tag->values(KnownField::Genre);
173 if (m_tagStatus == TagStatus::TestMetaDataPresent) {
174 CPPUNIT_ASSERT_EQUAL(2_st, genres.size());
175 CPPUNIT_ASSERT_EQUAL("Test"s, genres[0]->toString(TagTextEncoding::Utf8));
176 CPPUNIT_ASSERT_EQUAL("Example"s, genres[1]->toString(TagTextEncoding::Utf8));
177 } else {
178 CPPUNIT_ASSERT_EQUAL(4_st, genres.size());
179 CPPUNIT_ASSERT_EQUAL("Hardstyle"s, genres[0]->toString(TagTextEncoding::Utf8));
180 CPPUNIT_ASSERT_EQUAL("Test"s, genres[1]->toString(TagTextEncoding::Utf8));
181 CPPUNIT_ASSERT_EQUAL("Example"s, genres[2]->toString(TagTextEncoding::Utf8));
182 CPPUNIT_ASSERT_EQUAL("Hard Dance"s, genres[3]->toString(TagTextEncoding::Utf8));
183 }
184 }
185 break;
186 case TagStatus::Removed:
187 CPPUNIT_ASSERT_EQUAL(0_st, tags.size());
188 }
189
190 if (expectId3v24 || m_tagStatus == TagStatus::Removed) {
191 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Information);
192 return;
193 }
194
195 CPPUNIT_ASSERT(m_diag.level() <= DiagLevel::Warning);
196 int warningCount = 0;
197 for (const auto &msg : m_diag) {
198 if (msg.level() != DiagLevel::Warning) {
199 continue;
200 }
201 ++warningCount;
202 TESTUTILS_ASSERT_LIKE("context", "(parsing|making) (TPE1|TCON)( frame)?", msg.context());
203 TESTUTILS_ASSERT_LIKE("message",
204 "Multiple strings (found|assigned) .*"
205 "Additional (values \"Second Artist Example\" and \"3rd Artist Example\" are|"
206 "value \"Example\" is) "
207 "supposed to be ignored.",
208 msg.message());
209 }
210 CPPUNIT_ASSERT_EQUAL_MESSAGE("exactly 4 warnings present", 4, warningCount);
211}
212
216void OverallTests::checkMp3TestMetaData()
217{
218 using namespace Mp3TestFlags;
219
220 // check whether tags are assigned according to the current test mode
221 Id3v1Tag *id3v1Tag = nullptr;
222 Id3v2Tag *id3v2Tag = nullptr;
223 if (m_mode & Id3v2AndId3v1) {
224 CPPUNIT_ASSERT(id3v1Tag = m_fileInfo.id3v1Tag());
225 CPPUNIT_ASSERT(id3v2Tag = m_fileInfo.id3v2Tags().at(0).get());
226 } else if (m_mode & Id3v1Only) {
227 CPPUNIT_ASSERT(id3v1Tag = m_fileInfo.id3v1Tag());
228 CPPUNIT_ASSERT(m_fileInfo.id3v2Tags().empty());
229 } else {
230 CPPUNIT_ASSERT(!m_fileInfo.id3v1Tag());
231 CPPUNIT_ASSERT(id3v2Tag = m_fileInfo.id3v2Tags().at(0).get());
232 }
233
234 // check common test meta data
235 if (id3v1Tag) {
236 CPPUNIT_ASSERT_EQUAL(TagTextEncoding::Latin1, id3v1Tag->value(KnownField::Title).dataEncoding());
237 CPPUNIT_ASSERT_EQUAL(m_testTitle, id3v1Tag->value(KnownField::Title));
238 CPPUNIT_ASSERT_EQUAL(m_testCommentWithoutDescription, id3v1Tag->value(KnownField::Comment));
239 CPPUNIT_ASSERT_EQUAL(m_testAlbum, id3v1Tag->value(KnownField::Album));
240 CPPUNIT_ASSERT_EQUAL(m_preservedMetaData.front(), id3v1Tag->value(KnownField::Artist));
241 m_preservedMetaData.pop();
242 }
243 if (id3v2Tag) {
244 const TagValue &titleValue = id3v2Tag->value(KnownField::Title);
245 const TagValue &commentValue = id3v2Tag->value(KnownField::Comment);
246
247 if (m_mode & UseId3v24) {
248 CPPUNIT_ASSERT_EQUAL(TagTextEncoding::Utf8, titleValue.dataEncoding());
249 CPPUNIT_ASSERT_EQUAL(m_testTitle, titleValue);
250 CPPUNIT_ASSERT_EQUAL(m_testComment, commentValue);
251 CPPUNIT_ASSERT_EQUAL(m_testAlbum, id3v2Tag->value(KnownField::Album));
252 CPPUNIT_ASSERT_EQUAL(m_preservedMetaData.front(), id3v2Tag->value(KnownField::Artist));
253 // TODO: check more fields
254 } else {
255 CPPUNIT_ASSERT_EQUAL_MESSAGE("not attempted to use UTF-8 in ID3v2.3", TagTextEncoding::Utf16LittleEndian, titleValue.dataEncoding());
256 CPPUNIT_ASSERT_EQUAL(m_testTitle, titleValue);
257 CPPUNIT_ASSERT_EQUAL_MESSAGE("not attempted to use UTF-8 in ID3v2.3", TagTextEncoding::Utf16LittleEndian, commentValue.dataEncoding());
258 CPPUNIT_ASSERT_EQUAL_MESSAGE(
259 "not attempted to use UTF-8 in ID3v2.3", TagTextEncoding::Utf16LittleEndian, commentValue.descriptionEncoding());
260 CPPUNIT_ASSERT_EQUAL(m_testComment, commentValue);
261 CPPUNIT_ASSERT_EQUAL_MESSAGE(
262 "description is also converted to UTF-16", "s\0o\0m\0e\0 \0d\0e\0s\0c\0r\0i\0p\0t\0i\0\xf3\0n\0"s, commentValue.description());
263 CPPUNIT_ASSERT_EQUAL(m_testAlbum, id3v2Tag->value(KnownField::Album));
264 CPPUNIT_ASSERT_EQUAL(m_preservedMetaData.front(), id3v2Tag->value(KnownField::Artist));
265 // TODO: check more fields
266 }
267
268 m_preservedMetaData.pop();
269 }
270
271 // test ID3v1 specific test meta data
272 if (id3v1Tag) {
273 CPPUNIT_ASSERT_EQUAL(m_testPosition.toPositionInSet().position(), id3v1Tag->value(KnownField::TrackPosition).toPositionInSet().position());
274 }
275 // test ID3v2 specific test meta data
276 if (id3v2Tag) {
277 CPPUNIT_ASSERT_EQUAL(m_testPosition, id3v2Tag->value(KnownField::TrackPosition));
278 CPPUNIT_ASSERT_EQUAL(m_testPosition, id3v2Tag->value(KnownField::DiskPosition));
279 }
280}
281
285void OverallTests::checkMp3PaddingConstraints()
286{
287 using namespace Mp3TestFlags;
288
289 if (!(m_mode & Id3v1Only)) {
290 if (m_mode & PaddingConstraints) {
291 if (m_mode & ForceRewring) {
292 CPPUNIT_ASSERT_EQUAL(static_cast<std::uint64_t>(4096), m_fileInfo.paddingSize());
293 } else {
294 CPPUNIT_ASSERT(m_fileInfo.paddingSize() >= 1024);
295 CPPUNIT_ASSERT(m_fileInfo.paddingSize() <= (4096 + 1024));
296 }
297 }
298 } else {
299 // adding padding is not possible if no ID3v2 tag is present
300 }
301 // TODO: check rewriting behaviour
302}
303
307void OverallTests::setMp3TestMetaData1()
308{
309 using namespace Mp3TestFlags;
310
311 // ensure tags are assigned according to the current test mode
312 Id3v1Tag *id3v1Tag = nullptr;
313 Id3v2Tag *id3v2Tag = nullptr;
314 if (m_mode & Id3v2AndId3v1) {
315 id3v1Tag = m_fileInfo.createId3v1Tag();
316 id3v2Tag = m_fileInfo.createId3v2Tag();
317 } else if (m_mode & Id3v1Only) {
318 id3v1Tag = m_fileInfo.createId3v1Tag();
319 m_fileInfo.removeAllId3v2Tags();
320 } else {
321 m_fileInfo.removeId3v1Tag();
322 id3v2Tag = m_fileInfo.createId3v2Tag();
323 }
324 if (!(m_mode & Id3v1Only) && m_mode & UseId3v24) {
325 id3v2Tag->setVersion(4, 0);
326 }
327
328 // assign some test meta data
329 for (Tag *const tag : initializer_list<Tag *>{ id3v1Tag, id3v2Tag }) {
330 if (!tag) {
331 continue;
332 }
333 tag->setValue(KnownField::Title, m_testTitle);
334 tag->setValue(KnownField::Comment, m_testComment);
335 tag->setValue(KnownField::Album, m_testAlbum);
336 m_preservedMetaData.push(tag->value(KnownField::Artist));
337 tag->setValue(KnownField::TrackPosition, m_testPosition);
338 tag->setValue(KnownField::DiskPosition, m_testPosition);
339 // TODO: set more fields
340 }
341 if (id3v1Tag) {
342 id3v1Tag->ensureTextValuesAreProperlyEncoded();
343 }
344}
345
349void OverallTests::setMp3TestMetaData2()
350{
351 using namespace Mp3TestFlags;
352
353 CPPUNIT_ASSERT_EQUAL(1_st, m_fileInfo.id3v2Tags().size());
354 auto &id3v2Tag(m_fileInfo.id3v2Tags().front());
355 id3v2Tag->setVersion((m_mode & UseId3v24) ? 4 : 3, 0);
356 const auto artists = id3v2Tag->values(KnownField::Artist);
357 CPPUNIT_ASSERT_EQUAL(2_st, artists.size());
358 id3v2Tag->setValues(KnownField::Artist, { *artists[0], *artists[1], TagValue("3rd Artist Example") });
359 id3v2Tag->setValues(KnownField::Genre, { TagValue("Test"), TagValue("Example") });
360}
361
365 void OverallTests::testMp3Parsing()
366{
367 cerr << endl << "MP3 parser" << endl;
368 m_fileInfo.setForceFullParse(false);
369 m_tagStatus = TagStatus::Original;
370 parseFile(testFilePath("mtx-test-data/mp3/id3-tag-and-xing-header.mp3"), &OverallTests::checkMp3Testfile1);
371 parseFile(testFilePath("misc/multiple_id3v2_4_values.mp3"), &OverallTests::checkMp3Testfile2);
372}
373
378 void OverallTests::testMp3Making()
379{
380 // full parse is required to determine padding
381 m_fileInfo.setForceFullParse(true);
382
383 // do the test under different conditions
384 for (m_mode = 0; m_mode != 0x20; ++m_mode) {
385 using namespace Mp3TestFlags;
386
387 // setup test conditions
388 m_fileInfo.setForceRewrite(m_mode & ForceRewring);
389 if (m_mode & UseId3v24) {
390 if (m_mode & Id3v1Only) {
391 continue;
392 }
393 }
394 m_fileInfo.setTagPosition(ElementPosition::Keep);
395 m_fileInfo.setIndexPosition(ElementPosition::Keep);
396 m_fileInfo.setPreferredPadding(m_mode & PaddingConstraints ? 4096 : 0);
397 m_fileInfo.setMinPadding(m_mode & PaddingConstraints ? 1024 : 0);
398 m_fileInfo.setMaxPadding(m_mode & PaddingConstraints ? (4096 + 1024) : numeric_limits<size_t>::max());
399 m_fileInfo.setForceTagPosition(false);
400 m_fileInfo.setForceIndexPosition(false);
401
402 // print test conditions
403 list<string> testConditions;
404 if (m_mode & ForceRewring) {
405 testConditions.emplace_back("forcing rewrite");
406 }
407 if (m_mode & Id3v2AndId3v1) {
408 if (m_mode & RemoveTag) {
409 testConditions.emplace_back("removing tag");
410 } else {
411 testConditions.emplace_back("ID3v1 and ID3v2");
412 }
413 } else if (m_mode & Id3v1Only) {
414 testConditions.emplace_back("ID3v1 only");
415 } else {
416 testConditions.emplace_back("ID3v2 only");
417 }
418 if (m_mode & PaddingConstraints) {
419 testConditions.emplace_back("padding constraints");
420 }
421 if (m_mode & UseId3v24) {
422 testConditions.emplace_back("use ID3v2.4");
423 }
424 cerr << endl << "MP3 maker - testmode " << m_mode << ": " << joinStrings(testConditions, ", ") << endl;
425
426 // do actual tests
427 m_tagStatus = (m_mode & RemoveTag) ? TagStatus::Removed : TagStatus::TestMetaDataPresent;
428 makeFile(workingCopyPath("mtx-test-data/mp3/id3-tag-and-xing-header.mp3"),
429 (m_mode & RemoveTag) ? &OverallTests::removeAllTags : &OverallTests::setMp3TestMetaData1, &OverallTests::checkMp3Testfile1);
430 makeFile(workingCopyPath("misc/multiple_id3v2_4_values.mp3"),
431 (m_mode & RemoveTag) ? &OverallTests::removeAllTags : &OverallTests::setMp3TestMetaData2, &OverallTests::checkMp3Testfile2);
432 }
433}
abstracttrack.h
OverallTests::testMp3Parsing
void testMp3Parsing()
Tests the MP3 parser via MediaFileInfo.
Definition overallmp3.cpp:365
OverallTests::testMp3Making
void testMp3Making()
Tests the MP3 maker via MediaFileInfo.
Definition overallmp3.cpp:378
TagParser::FieldMapBasedTag::value
const TagValue & value(const IdentifierType &id) const
Returns the value of the field with the specified id.
Definition fieldbasedtag.h:161
TagParser::FieldMapBasedTag::values
std::vector< const TagValue * > values(const IdentifierType &id) const
Returns the values of the field with the specified id.
Definition fieldbasedtag.h:175
TagParser::FieldMapBasedTag::setValues
bool setValues(const IdentifierType &id, const std::vector< TagValue > &values)
Assigns the given values to the field with the specified id.
Definition fieldbasedtag.h:265
TagParser::Id3v1Tag::ensureTextValuesAreProperlyEncoded
void ensureTextValuesAreProperlyEncoded() override
Ensures the encoding of all assigned text values is supported by the tag by converting the character ...
Definition id3v1tag.cpp:260
TagParser::Id3v1Tag::value
const TagValue & value(KnownField value) const override
Returns the value of the specified field.
Definition id3v1tag.cpp:144
TagParser::Id3v2Tag::setVersion
void setVersion(std::uint8_t majorVersion, std::uint8_t revisionVersion)
Sets the version to the specified majorVersion and the specified revisionVersion.
Definition id3v2tag.cpp:691
TagParser::PositionInSet::position
constexpr std::int32_t position() const
Returns the element position of the current instance.
Definition positioninset.h:80
TagParser::TagValue::dataEncoding
TagTextEncoding dataEncoding() const
Returns the data encoding.
Definition tagvalue.h:718
TagParser::TagValue::toPositionInSet
PositionInSet toPositionInSet() const
Converts the value of the current TagValue object to its equivalent PositionInSet representation.
Definition tagvalue.cpp:675
TagParser::TagValue::descriptionEncoding
TagTextEncoding descriptionEncoding() const
Returns the description encoding.
Definition tagvalue.h:728
TagParser::TagValue::description
const std::string & description() const
Returns the description.
Definition tagvalue.h:561
helper.h
id3v1tag.h
id3v2tag.h
mpegaudioframe.h
Mp3TestFlags
Definition overallmp3.cpp:11
Mp3TestFlags::TestFlag
TestFlag
Definition overallmp3.cpp:12
Mp3TestFlags::Id3v1Only
@ Id3v1Only
Definition overallmp3.cpp:16
Mp3TestFlags::ForceRewring
@ ForceRewring
Definition overallmp3.cpp:13
Mp3TestFlags::RemoveTag
@ RemoveTag
Definition overallmp3.cpp:17
Mp3TestFlags::Id3v2AndId3v1
@ Id3v2AndId3v1
Definition overallmp3.cpp:14
Mp3TestFlags::PaddingConstraints
@ PaddingConstraints
Definition overallmp3.cpp:15
Mp3TestFlags::UseId3v24
@ UseId3v24
Definition overallmp3.cpp:18
TagParser::Id3v2FrameIds::lGenre
@ lGenre
Definition id3v2frameids.h:27
TagParser::SubFormats::Mpeg1Layer3
@ Mpeg1Layer3
Definition mediaformat.h:114
TagParser::ElementPosition::Keep
@ Keep
Definition settings.h:16
TagParser::TagType::Id3v1Tag
@ Id3v1Tag
Definition tagtype.h:13
TagParser::ContainerFormat::Id3v2Tag
@ Id3v2Tag
Definition signature.h:33
overall.h
TagStatus::Original
@ Original
Definition overall.h:28
TagStatus::Removed
@ Removed
Definition overall.h:28
TagStatus::TestMetaDataPresent
@ TestMetaDataPresent
Definition overall.h:28