Audacity 3.2.0
Public Types | Public Member Functions | Static Public Member Functions | Private Attributes | Friends | List of all members
Tags Class Referencefinal

ID3 Tags (for MP3) More...

#include <Tags.h>

Inheritance diagram for Tags:
[legend]
Collaboration diagram for Tags:
[legend]

Public Types

using Iterators = IteratorRange< TagMap::const_iterator >
 

Public Member Functions

 Tags ()
 
 Tags (const Tags &)=default
 
virtual ~Tags ()
 
std::shared_ptr< TagsDuplicate () const
 
void Merge (const Tags &other)
 
Tagsoperator= (const Tags &src)
 
bool HandleXMLTag (const std::string_view &tag, const AttributesList &attrs) override
 
XMLTagHandlerHandleXMLChild (const std::string_view &tag) override
 
void WriteXML (XMLWriter &xmlFile) const
 
void LoadDefaultGenres ()
 
void LoadGenres ()
 
void LoadDefaults ()
 
int GetNumUserGenres ()
 
wxString GetUserGenre (int value)
 
wxString GetGenre (int value)
 
int GetGenre (const wxString &name)
 
bool HasTag (const wxString &name) const
 
wxString GetTag (const wxString &name) const
 
Iterators GetRange () const
 
void SetTag (const wxString &name, const wxString &value, const bool bSpecialTag=false)
 
void SetTag (const wxString &name, const int &value)
 
bool IsEmpty ()
 
void Clear ()
 
void RestoreUndoRedoState (AudacityProject &) override
 Modify the project when undoing or redoing to some state in history. More...
 
- Public Member Functions inherited from XMLTagHandler
 XMLTagHandler ()
 
virtual ~XMLTagHandler ()
 
virtual bool HandleXMLTag (const std::string_view &tag, const AttributesList &attrs)=0
 
virtual void HandleXMLEndTag (const std::string_view &WXUNUSED(tag))
 
virtual void HandleXMLContent (const std::string_view &WXUNUSED(content))
 
virtual XMLTagHandlerHandleXMLChild (const std::string_view &tag)=0
 
void ReadXMLEndTag (const char *tag)
 
void ReadXMLContent (const char *s, int len)
 
XMLTagHandlerReadXMLChild (const char *tag)
 
- Public Member Functions inherited from ClientData::Base
virtual ~Base ()
 
- Public Member Functions inherited from UndoStateExtension
virtual ~UndoStateExtension ()
 
virtual void RestoreUndoRedoState (AudacityProject &project)=0
 Modify the project when undoing or redoing to some state in history. More...
 
virtual bool CanUndoOrRedo (const AudacityProject &project)
 Whether undo or redo is now permitted; default returns true. More...
 

Static Public Member Functions

static TagsGet (AudacityProject &project)
 
static const TagsGet (const AudacityProject &project)
 
static TagsSet (AudacityProject &project, const std::shared_ptr< Tags > &tags)
 

Private Attributes

TagMap mXref
 
TagMap mMap
 
wxArrayString mGenres
 

Friends

TAGS_API bool operator== (const Tags &lhs, const Tags &rhs)
 

Detailed Description

ID3 Tags (for MP3)

This class started as an ID3 tag

This class holds a few informational tags, such as Title, Author, etc. that can be associated with a project or other audio file. It is modeled after the ID3 format for MP3 files, and it can both import and export ID3 tags from/to MP2, MP3, and AIFF files.

It can present the user with a dialog for editing this information.

Use of this functionality requires that libid3tag be compiled in with Audacity.

Definition at line 68 of file Tags.h.

Member Typedef Documentation

◆ Iterators

using Tags::Iterators = IteratorRange<TagMap::const_iterator>

Definition at line 112 of file Tags.h.

Constructor & Destructor Documentation

◆ Tags() [1/2]

Tags::Tags ( )

Definition at line 231 of file Tags.cpp.

232{
233 LoadDefaults();
234 LoadGenres();
235}
void LoadGenres()
Definition: Tags.cpp:356
void LoadDefaults()
Definition: Tags.cpp:266

References LoadDefaults(), and LoadGenres().

Here is the call graph for this function:

◆ Tags() [2/2]

Tags::Tags ( const Tags )
default

◆ ~Tags()

Tags::~Tags ( )
virtual

Definition at line 237 of file Tags.cpp.

238{
239}

Member Function Documentation

◆ Clear()

void Tags::Clear ( )

Definition at line 308 of file Tags.cpp.

309{
310 mXref.clear();
311 mMap.clear();
312}
TagMap mXref
Definition: Tags.h:127
TagMap mMap
Definition: Tags.h:128

References mMap, and mXref.

Referenced by FLACImportFileHandle::Import(), OggImportFileHandle::Import(), WavPackImportFileHandle::Import(), MP3ImportFileHandle::LoadID3(), TagsEditorDialog::OnClear(), and TagsEditorDialog::TransferDataFromWindow().

Here is the caller graph for this function:

◆ Duplicate()

std::shared_ptr< Tags > Tags::Duplicate ( ) const

Definition at line 241 of file Tags.cpp.

242{
243 return std::make_shared<Tags>(*this);
244}

◆ Get() [1/2]

Tags & Tags::Get ( AudacityProject project)
static

Definition at line 214 of file Tags.cpp.

215{
216 return project.AttachedObjects::Get< Tags >( key );
217}
static const AudacityProject::AttachedObjects::RegisteredFactory key
Definition: Tags.cpp:210
ID3 Tags (for MP3)
Definition: Tags.h:73

References key.

Referenced by TagsEditorDialog::DoEditMetadata(), ExportCL::Export(), ExportMP3::Export(), ExportPCM::Export(), ExportWavPack::Export(), ExportMultipleDialog::ExportMultipleByLabel(), ExportMultipleDialog::ExportMultipleByTrack(), ExportOGG::FillComment(), Get(), ExportFLAC::GetMetadata(), ProjectFileManager::Import(), anonymous_namespace{ProjectFileManager.cpp}::ImportProject(), and ExportFFmpeg::Init().

Here is the caller graph for this function:

◆ Get() [2/2]

const Tags & Tags::Get ( const AudacityProject project)
static

Definition at line 219 of file Tags.cpp.

220{
221 return Get( const_cast< AudacityProject & >( project ) );
222}
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
static Tags & Get(AudacityProject &project)
Definition: Tags.cpp:214

References Get().

Here is the call graph for this function:

◆ GetGenre() [1/2]

int Tags::GetGenre ( const wxString &  name)

Definition at line 394 of file Tags.cpp.

395{
396 int cnt = WXSIZEOF(DefaultGenres);
397
398 for (int i = 0; i < cnt; i++) {
399 if (name.CmpNoCase(DefaultGenres[i])) {
400 return i;
401 }
402 }
403
404 return 255;
405}
const TranslatableString name
Definition: Distortion.cpp:76
static const wxChar * DefaultGenres[]
Definition: Tags.cpp:50

References DefaultGenres, and name.

◆ GetGenre() [2/2]

wxString Tags::GetGenre ( int  value)

Definition at line 383 of file Tags.cpp.

384{
385 int cnt = WXSIZEOF(DefaultGenres);
386
387 if (i >= 0 && i < cnt) {
388 return DefaultGenres[i];
389 }
390
391 return wxT("");
392}
wxT("CloseDown"))

References DefaultGenres, and wxT().

Referenced by anonymous_namespace{ImportMP3_MPG123.cpp}::GetId3v2Genre(), PCMImportFileHandle::Import(), MP3ImportFileHandle::LoadID3(), and anonymous_namespace{ImportMP3_MPG123.cpp}::MP3ImportFileHandle::ReadTags().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetNumUserGenres()

int Tags::GetNumUserGenres ( )

Definition at line 343 of file Tags.cpp.

344{
345 return mGenres.size();
346}
wxArrayString mGenres
Definition: Tags.h:130

References mGenres.

Referenced by GetUserGenre(), TagsEditorDialog::OnEdit(), TagsEditorDialog::OnReset(), and TagsEditorDialog::PopulateGenres().

Here is the caller graph for this function:

◆ GetRange()

Tags::Iterators Tags::GetRange ( ) const

Definition at line 436 of file Tags.cpp.

437{
438 return { mMap.begin(), mMap.end() };
439}

References mMap.

Referenced by ExportPCM::AddID3Chunk(), ExportMP3::AddTags(), ExportWavPack::Export(), ExportOGG::FillComment(), ExportCL::GetMetaChunk(), ExportFLAC::GetMetadata(), TagsEditorDialog::OnSaveDefaults(), and TagsEditorDialog::TransferDataToWindow().

Here is the caller graph for this function:

◆ GetTag()

wxString Tags::GetTag ( const wxString &  name) const

Definition at line 416 of file Tags.cpp.

417{
418 wxString key = name;
419 key.UpperCase();
420
421 auto iter = mXref.find(key);
422
423 if (iter == mXref.end()) {
424 return wxEmptyString;
425 }
426
427 auto iter2 = mMap.find(iter->second);
428 if (iter2 == mMap.end()) {
429 wxASSERT(false);
430 return wxEmptyString;
431 }
432 else
433 return iter2->second;
434}

References key, mMap, mXref, and name.

Referenced by ExportPCM::AddStrings(), PCMImportFileHandle::Import(), MP3ImportFileHandle::LoadID3(), TagsEditorDialog::OnLoad(), TagsEditorDialog::OnSave(), TagsEditorDialog::OnSaveDefaults(), ExportFFmpeg::SetMetadata(), and TagsEditorDialog::TransferDataToWindow().

Here is the caller graph for this function:

◆ GetUserGenre()

wxString Tags::GetUserGenre ( int  value)

Definition at line 374 of file Tags.cpp.

375{
376 if (i >= 0 && i < GetNumUserGenres()) {
377 return mGenres[i];
378 }
379
380 return wxT("");
381}
int GetNumUserGenres()
Definition: Tags.cpp:343

References GetNumUserGenres(), mGenres, and wxT().

Referenced by TagsEditorDialog::OnEdit(), TagsEditorDialog::OnReset(), and TagsEditorDialog::PopulateGenres().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ HandleXMLChild()

XMLTagHandler * Tags::HandleXMLChild ( const std::string_view &  tag)
overridevirtual

Implements XMLTagHandler.

Definition at line 536 of file Tags.cpp.

537{
538 if (tag == "tags") {
539 return this;
540 }
541
542 if (tag == "tag") {
543 return this;
544 }
545
546 return NULL;
547}

◆ HandleXMLTag()

bool Tags::HandleXMLTag ( const std::string_view &  tag,
const AttributesList attrs 
)
overridevirtual

Implements XMLTagHandler.

Definition at line 501 of file Tags.cpp.

502{
503 if (tag == "tags") {
504 return true;
505 }
506
507 if (tag == "tag") {
508 wxString n, v;
509
510 for (auto pair : attrs)
511 {
512 auto attr = pair.first;
513 auto value = pair.second;
514
515 if (attr == "name") {
516 n = value.ToWString();
517 }
518 else if (attr == "value") {
519 v = value.ToWString();
520 }
521 }
522
523 if (n == wxT("id3v2")) {
524 // LLL: This is obsolete, but it must be handled and ignored.
525 }
526 else {
527 SetTag(n, v);
528 }
529
530 return true;
531 }
532
533 return false;
534}
void SetTag(const wxString &name, const wxString &value, const bool bSpecialTag=false)
Definition: Tags.cpp:441

References SetTag(), and wxT().

Here is the call graph for this function:

◆ HasTag()

bool Tags::HasTag ( const wxString &  name) const

Definition at line 407 of file Tags.cpp.

408{
409 wxString key = name;
410 key.UpperCase();
411
412 auto iter = mXref.find(key);
413 return (iter != mXref.end());
414}

References key, mXref, and name.

Referenced by ExportPCM::AddStrings(), FLACImportFileHandle::Import(), OggImportFileHandle::Import(), PCMImportFileHandle::Import(), WavPackImportFileHandle::Import(), IsEmpty(), MP3ImportFileHandle::LoadID3(), and ExportFFmpeg::SetMetadata().

Here is the caller graph for this function:

◆ IsEmpty()

bool Tags::IsEmpty ( )

Definition at line 297 of file Tags.cpp.

298{
299 // At least one of these should be filled in, otherwise
300 // it's assumed that the tags have not been set...
302 return false;
303 }
304
305 return true;
306}
#define TAG_ALBUM
Definition: Tags.h:60
#define TAG_TITLE
Definition: Tags.h:58
#define TAG_ARTIST
Definition: Tags.h:59
bool HasTag(const wxString &name) const
Definition: Tags.cpp:407

References HasTag(), TAG_ALBUM, TAG_ARTIST, and TAG_TITLE.

Referenced by FFmpegImportFileHandle::WriteMetadata().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ LoadDefaultGenres()

void Tags::LoadDefaultGenres ( )

Definition at line 348 of file Tags.cpp.

349{
350 mGenres.clear();
351 for (size_t i = 0; i < WXSIZEOF(DefaultGenres); i++) {
352 mGenres.push_back(DefaultGenres[i]);
353 }
354}

References DefaultGenres, and mGenres.

Referenced by LoadGenres(), and TagsEditorDialog::OnReset().

Here is the caller graph for this function:

◆ LoadDefaults()

void Tags::LoadDefaults ( )

Definition at line 266 of file Tags.cpp.

267{
268 wxString path;
269 wxString name;
270 wxString value;
271 long ndx;
272 bool cont;
273
274 // Set the parent group
275 path = gPrefs->GetPath();
276 gPrefs->SetPath(wxT("/Tags"));
277
278 // Process all entries in the group
279 cont = gPrefs->GetFirstEntry(name, ndx);
280 while (cont) {
281 gPrefs->Read(name, &value, wxT(""));
282
283 if (name == wxT("ID3V2")) {
284 // LLL: This is obsolute, but it must be handled and ignored.
285 }
286 else {
287 SetTag(name, value);
288 }
289
290 cont = gPrefs->GetNextEntry(name, ndx);
291 }
292
293 // Restore original group
294 gPrefs->SetPath(path);
295}
FileConfig * gPrefs
Definition: Prefs.cpp:70
virtual bool GetNextEntry(wxString &str, long &lIndex) const wxOVERRIDE
Definition: FileConfig.cpp:118
virtual const wxString & GetPath() const wxOVERRIDE
Definition: FileConfig.cpp:98
virtual void SetPath(const wxString &strPath) wxOVERRIDE
Definition: FileConfig.cpp:93
virtual bool GetFirstEntry(wxString &str, long &lIndex) const wxOVERRIDE
Definition: FileConfig.cpp:113

References FileConfig::GetFirstEntry(), FileConfig::GetNextEntry(), FileConfig::GetPath(), gPrefs, name, FileConfig::SetPath(), SetTag(), and wxT().

Referenced by Tags().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ LoadGenres()

void Tags::LoadGenres ( )

Definition at line 356 of file Tags.cpp.

357{
358 wxFileName fn(FileNames::DataDir(), wxT("genres.txt"));
359 wxTextFile tf(fn.GetFullPath());
360
361 if (!tf.Exists() || !tf.Open()) {
363 return;
364 }
365
366 mGenres.clear();
367
368 int cnt = tf.GetLineCount();
369 for (int i = 0; i < cnt; i++) {
370 mGenres.push_back(tf.GetLine(i));
371 }
372}
static const auto fn
void LoadDefaultGenres()
Definition: Tags.cpp:348
FILES_API FilePath DataDir()
Audacity user data directory.

References FileNames::DataDir(), fn, LoadDefaultGenres(), mGenres, and wxT().

Referenced by TagsEditorDialog::OnEdit(), TagsEditorDialog::OnReset(), and Tags().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Merge()

void Tags::Merge ( const Tags other)

Definition at line 246 of file Tags.cpp.

247{
248 for ( auto &pair : other.mMap ) {
249 SetTag( pair.first, pair.second );
250 }
251}

References mMap, and SetTag().

Referenced by anonymous_namespace{ProjectFileManager.cpp}::ImportProject().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ operator=()

Tags & Tags::operator= ( const Tags src)

Definition at line 253 of file Tags.cpp.

254{
255 mXref.clear();
256 mXref = src.mXref;
257 mMap.clear();
258 mMap = src.mMap;
259
260 mGenres.clear();
261 mGenres = src.mGenres;
262
263 return *this;
264}

References mGenres, mMap, and mXref.

◆ RestoreUndoRedoState()

void Tags::RestoreUndoRedoState ( AudacityProject project)
overridevirtual

Modify the project when undoing or redoing to some state in history.

Implements UndoStateExtension.

Definition at line 579 of file Tags.cpp.

580{
581 // Restore tags
582 Tags::Set( project, shared_from_this() );
583}
static Tags & Set(AudacityProject &project, const std::shared_ptr< Tags > &tags)
Definition: Tags.cpp:224

References Set().

Here is the call graph for this function:

◆ Set()

Tags & Tags::Set ( AudacityProject project,
const std::shared_ptr< Tags > &  tags 
)
static

Definition at line 224 of file Tags.cpp.

225{
226 auto &result = *tags;
227 project.AttachedObjects::Assign( key, tags );
228 return result;
229}

References key.

Referenced by TagsEditorDialog::DoEditMetadata(), ProjectFileManager::Import(), and RestoreUndoRedoState().

Here is the caller graph for this function:

◆ SetTag() [1/2]

void Tags::SetTag ( const wxString &  name,
const int &  value 
)

Definition at line 496 of file Tags.cpp.

497{
498 SetTag(name, wxString::Format(wxT("%d"), value));
499}

References name, SetTag(), and wxT().

Here is the call graph for this function:

◆ SetTag() [2/2]

void Tags::SetTag ( const wxString &  name,
const wxString &  value,
const bool  bSpecialTag = false 
)

Definition at line 441 of file Tags.cpp.

442{
443 // We don't like empty names
444 if (name.empty()) {
445 return;
446 }
447
448 // Tag name must be ascii
449 if (!name.IsAscii()) {
450 wxLogError("Tag rejected (Non-ascii character in name)");
451 return;
452 }
453
454 // All keys are uppercase
455 wxString key = name;
456 key.UpperCase();
457
458 // Look it up
459 TagMap::iterator iter = mXref.find(key);
460
461 // The special tags, if empty, should not exist.
462 // However it is allowable for a custom tag to be empty.
463 // See Bug 440 and Bug 1382
464 if (value.empty() && bSpecialTag) {
465 // Erase the tag
466 if (iter == mXref.end())
467 // nothing to do
468 ;
469 else {
470 mMap.erase(iter->second);
471 mXref.erase(iter);
472 }
473 }
474 else
475 {
476 if (iter == mXref.end()) {
477 // Didn't find the tag
478
479 // Add a NEW tag
480 mXref[key] = name;
481 mMap[name] = value;
482 }
483 else if (iter->second != name) {
484 // Watch out for case differences!
485 mMap[name] = value;
486 mMap.erase(iter->second);
487 iter->second = name;
488 }
489 else {
490 // Update the value
491 mMap[iter->second] = value;
492 }
493 }
494}

References TranslatableString::empty(), key, mMap, mXref, and name.

Referenced by FFmpegImportFileHandle::GetMetadata(), AUPImportFileHandle::HandleTag(), AUPImportFileHandle::HandleTags(), HandleXMLTag(), FLACImportFileHandle::Import(), OggImportFileHandle::Import(), PCMImportFileHandle::Import(), WavPackImportFileHandle::Import(), LoadDefaults(), MP3ImportFileHandle::LoadID3(), Merge(), TagsEditorDialog::OnLoad(), TagsEditorDialog::OnSave(), TagsEditorDialog::OnSaveDefaults(), GStreamerImportFileHandle::OnTag(), anonymous_namespace{ImportMP3_MPG123.cpp}::MP3ImportFileHandle::ReadTags(), SetTag(), and TagsEditorDialog::TransferDataFromWindow().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ WriteXML()

void Tags::WriteXML ( XMLWriter xmlFile) const

Definition at line 549 of file Tags.cpp.

551{
552 xmlFile.StartTag(wxT("tags"));
553
554 for (const auto &pair : GetRange()) {
555 const auto &n = pair.first;
556 const auto &v = pair.second;
557 xmlFile.StartTag(wxT("tag"));
558 xmlFile.WriteAttr(wxT("name"), n);
559 xmlFile.WriteAttr(wxT("value"), v);
560 xmlFile.EndTag(wxT("tag"));
561 }
562
563 xmlFile.EndTag(wxT("tags"));
564}
Iterators GetRange() const
Definition: Tags.cpp:436
virtual void StartTag(const wxString &name)
Definition: XMLWriter.cpp:79
void WriteAttr(const wxString &name, const Identifier &value)
Definition: XMLWriter.h:36
virtual void EndTag(const wxString &name)
Definition: XMLWriter.cpp:102

References wxT().

Referenced by TagsEditorDialog::OnSave().

Here is the call graph for this function:
Here is the caller graph for this function:

Friends And Related Function Documentation

◆ operator==

TAGS_API bool operator== ( const Tags lhs,
const Tags rhs 
)
friend

Definition at line 332 of file Tags.cpp.

333{
334 if (!EqualMaps(lhs.mXref, rhs.mXref))
335 return false;
336
337 if (!EqualMaps(lhs.mMap, rhs.mMap))
338 return false;
339
340 return lhs.mGenres == rhs.mGenres;
341}
bool EqualMaps(const TagMap &map1, const TagMap &map2)
Definition: Tags.cpp:315

Member Data Documentation

◆ mGenres

wxArrayString Tags::mGenres
private

Definition at line 130 of file Tags.h.

Referenced by GetNumUserGenres(), GetUserGenre(), LoadDefaultGenres(), LoadGenres(), and operator=().

◆ mMap

TagMap Tags::mMap
private

Definition at line 128 of file Tags.h.

Referenced by Clear(), GetRange(), GetTag(), Merge(), operator=(), and SetTag().

◆ mXref

TagMap Tags::mXref
private

Definition at line 127 of file Tags.h.

Referenced by Clear(), GetTag(), HasTag(), operator=(), and SetTag().


The documentation for this class was generated from the following files: