Bugs 188 and 225

Refer to bugzilla for discussion, but, to summarize, this removes any writing of ID3V1 tags.  ID3V1 tags will still be imported, but they will be written as ID3V2 tags.
This commit is contained in:
lllucius 2011-03-01 07:06:58 +00:00
parent 031a9e0af3
commit 60af76d2b3
6 changed files with 37 additions and 102 deletions

View File

@ -16,18 +16,10 @@
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 ID3 tags from MP3 files, and export them as well.
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.
It only keeps track of the fields that are standard in ID3v1
(title, author, artist, track num, year, genre, and comments),
but it can export both ID3v1 or the newer ID3v2 format. The primary
reason you would want to export ID3v2 tags instead of ID3v1,
since we're not supporting any v2 fields, is that ID3v2 tags are
inserted at the BEGINNING of an mp3 file, which is far more
useful for streaming.
Use of this functionality requires that libid3tag be compiled in
with Audacity.
@ -238,8 +230,6 @@ static const wxChar *DefaultGenres[] =
Tags::Tags()
{
mID3V2 = true;
mEditTitle = true;
mEditTrackNumber = true;
@ -253,8 +243,6 @@ Tags::~Tags()
Tags & Tags::operator=(const Tags & src)
{
mID3V2 = src.mID3V2;
mEditTitle = src.mEditTitle;
mEditTrackNumber = src.mEditTrackNumber;
@ -287,7 +275,7 @@ void Tags::LoadDefaults()
gPrefs->Read(name, &value, wxT(""));
if (name == wxT("ID3V2")) {
mID3V2 = value == wxT("1");
// LLL: This is obsolute, but it must be handled and ignored.
}
else {
SetTag(name, value);
@ -313,21 +301,10 @@ bool Tags::IsEmpty()
void Tags::Clear()
{
mID3V2 = true;
mXref.clear();
mMap.clear();
}
void Tags::SetID3V2(bool id3v2)
{
mID3V2 = id3v2;
}
bool Tags::GetID3V2()
{
return mID3V2;
}
void Tags::AllowEditTitle(bool editTitle)
{
mEditTitle = editTitle;
@ -523,10 +500,7 @@ bool Tags::HandleXMLTag(const wxChar *tag, const wxChar **attrs)
}
if (n == wxT("id3v2")) {
long nValue;
if (XMLValueChecker::IsGoodInt(v) && v.ToLong(&nValue)) {
mID3V2 = (nValue != 0);
}
// LLL: This is obsolute, but it must be handled and ignored.
}
else {
SetTag(n, v);
@ -555,11 +529,6 @@ void Tags::WriteXML(XMLWriter &xmlFile)
{
xmlFile.StartTag(wxT("tags"));
xmlFile.StartTag(wxT("tag"));
xmlFile.WriteAttr(wxT("name"), wxT("id3v2"));
xmlFile.WriteAttr(wxT("value"), mID3V2);
xmlFile.EndTag(wxT("tag"));
wxString n, v;
for (bool cont = GetFirst(n, v); cont; cont = GetNext(n, v)) {
xmlFile.StartTag(wxT("tag"));

View File

@ -74,9 +74,6 @@ class Tags: public XMLTagHandler {
virtual XMLTagHandler *HandleXMLChild(const wxChar *tag);
virtual void WriteXML(XMLWriter &xmlFile);
void SetID3V2(bool id3v2);
bool GetID3V2();
void AllowEditTitle(bool editTitle);
void AllowEditTrackNumber(bool editTrackNumber);
@ -104,8 +101,6 @@ class Tags: public XMLTagHandler {
private:
void LoadDefaults();
bool mID3V2;
TagMap::iterator mIter;
TagMap mXref;
TagMap mMap;

View File

@ -187,7 +187,7 @@ private:
int AddTags(AudacityProject *project, char **buffer, bool *endOfFile, Tags *tags);
#ifdef USE_LIBID3TAG
void AddFrame(struct id3_tag *tp, bool v2, const wxString & n, const wxString & v, const char *name);
void AddFrame(struct id3_tag *tp, const wxString & n, const wxString & v, const char *name);
#endif
};
@ -344,8 +344,6 @@ int ExportMP2::AddTags(AudacityProject *project, char **buffer, bool *endOfFile,
#ifdef USE_LIBID3TAG
struct id3_tag *tp = id3_tag_new();
bool v2 = tags->GetID3V2();
wxString n, v;
for (bool cont = tags->GetFirst(n, v); cont; cont = tags->GetNext(n, v)) {
const char *name = "TXXX";
@ -362,14 +360,11 @@ int ExportMP2::AddTags(AudacityProject *project, char **buffer, bool *endOfFile,
else if (n.CmpNoCase(TAG_YEAR) == 0) {
// LLL: Some apps do not like the newer frame ID (ID3_FRAME_YEAR),
// so we add old one as well.
AddFrame(tp, v2, n, v, "TYER");
AddFrame(tp, n, v, "TYER");
name = ID3_FRAME_YEAR;
}
else if (n.CmpNoCase(TAG_GENRE) == 0) {
name = ID3_FRAME_GENRE;
if (!v2) {
v.Printf(wxT("%d"), tags->GetGenre(v));
}
}
else if (n.CmpNoCase(TAG_COMMENTS) == 0) {
name = ID3_FRAME_COMMENT;
@ -378,25 +373,19 @@ int ExportMP2::AddTags(AudacityProject *project, char **buffer, bool *endOfFile,
name = ID3_FRAME_TRACK;
}
AddFrame(tp, v2, n, v, name);
AddFrame(tp, n, v, name);
}
if (v2) {
tp->options &= (~ID3_TAG_OPTION_COMPRESSION); // No compression
tp->options &= (~ID3_TAG_OPTION_COMPRESSION); // No compression
// If this version of libid3tag supports it, use v2.3 ID3
// tags instead of the newer, but less well supported, v2.4
// that libid3tag uses by default.
#ifdef ID3_TAG_HAS_TAG_OPTION_ID3V2_3
tp->options |= ID3_TAG_OPTION_ID3V2_3;
#endif
// If this version of libid3tag supports it, use v2.3 ID3
// tags instead of the newer, but less well supported, v2.4
// that libid3tag uses by default.
#ifdef ID3_TAG_HAS_TAG_OPTION_ID3V2_3
tp->options |= ID3_TAG_OPTION_ID3V2_3;
#endif
*endOfFile = false;
}
else {
tp->options |= ID3_TAG_OPTION_ID3V1;
*endOfFile = true;
}
*endOfFile = false;
id3_length_t len;
@ -413,17 +402,15 @@ int ExportMP2::AddTags(AudacityProject *project, char **buffer, bool *endOfFile,
}
#ifdef USE_LIBID3TAG
void ExportMP2::AddFrame(struct id3_tag *tp, bool v2, const wxString & n, const wxString & v, const char *name)
void ExportMP2::AddFrame(struct id3_tag *tp, const wxString & n, const wxString & v, const char *name)
{
struct id3_frame *frame = id3_frame_new(name);
if (v2) {
if (!n.IsAscii() || !v.IsAscii()) {
id3_field_settextencoding(id3_frame_field(frame, 0), ID3_FIELD_TEXTENCODING_UTF_16);
}
else {
id3_field_settextencoding(id3_frame_field(frame, 0), ID3_FIELD_TEXTENCODING_ISO_8859_1);
}
if (!n.IsAscii() || !v.IsAscii()) {
id3_field_settextencoding(id3_frame_field(frame, 0), ID3_FIELD_TEXTENCODING_UTF_16);
}
else {
id3_field_settextencoding(id3_frame_field(frame, 0), ID3_FIELD_TEXTENCODING_ISO_8859_1);
}
id3_ucs4_t *ucs4 =

View File

@ -1486,7 +1486,7 @@ private:
int AskResample(int bitrate, int rate, int lowrate, int highrate);
int AddTags(AudacityProject *project, char **buffer, bool *endOfFile, Tags *tags);
#ifdef USE_LIBID3TAG
void AddFrame(struct id3_tag *tp, bool v2, const wxString & n, const wxString & v, const char *name);
void AddFrame(struct id3_tag *tp, const wxString & n, const wxString & v, const char *name);
#endif
};
@ -1848,8 +1848,6 @@ int ExportMP3::AddTags(AudacityProject *project, char **buffer, bool *endOfFile,
#ifdef USE_LIBID3TAG
struct id3_tag *tp = id3_tag_new();
bool v2 = tags->GetID3V2();
wxString n, v;
for (bool cont = tags->GetFirst(n, v); cont; cont = tags->GetNext(n, v)) {
const char *name = "TXXX";
@ -1866,14 +1864,11 @@ int ExportMP3::AddTags(AudacityProject *project, char **buffer, bool *endOfFile,
else if (n.CmpNoCase(TAG_YEAR) == 0) {
// LLL: Some apps do not like the newer frame ID (ID3_FRAME_YEAR),
// so we add old one as well.
AddFrame(tp, v2, n, v, "TYER");
AddFrame(tp, n, v, "TYER");
name = ID3_FRAME_YEAR;
}
else if (n.CmpNoCase(TAG_GENRE) == 0) {
name = ID3_FRAME_GENRE;
if (!v2) {
v.Printf(wxT("%d"), tags->GetGenre(v));
}
}
else if (n.CmpNoCase(TAG_COMMENTS) == 0) {
name = ID3_FRAME_COMMENT;
@ -1882,25 +1877,19 @@ int ExportMP3::AddTags(AudacityProject *project, char **buffer, bool *endOfFile,
name = ID3_FRAME_TRACK;
}
AddFrame(tp, v2, n, v, name);
AddFrame(tp, n, v, name);
}
if (v2) {
tp->options &= (~ID3_TAG_OPTION_COMPRESSION); // No compression
tp->options &= (~ID3_TAG_OPTION_COMPRESSION); // No compression
// If this version of libid3tag supports it, use v2.3 ID3
// tags instead of the newer, but less well supported, v2.4
// that libid3tag uses by default.
#ifdef ID3_TAG_HAS_TAG_OPTION_ID3V2_3
tp->options |= ID3_TAG_OPTION_ID3V2_3;
#endif
// If this version of libid3tag supports it, use v2.3 ID3
// tags instead of the newer, but less well supported, v2.4
// that libid3tag uses by default.
#ifdef ID3_TAG_HAS_TAG_OPTION_ID3V2_3
tp->options |= ID3_TAG_OPTION_ID3V2_3;
#endif
*endOfFile = false;
}
else {
tp->options |= ID3_TAG_OPTION_ID3V1;
*endOfFile = true;
}
*endOfFile = false;
id3_length_t len;
@ -1917,17 +1906,15 @@ int ExportMP3::AddTags(AudacityProject *project, char **buffer, bool *endOfFile,
}
#ifdef USE_LIBID3TAG
void ExportMP3::AddFrame(struct id3_tag *tp, bool v2, const wxString & n, const wxString & v, const char *name)
void ExportMP3::AddFrame(struct id3_tag *tp, const wxString & n, const wxString & v, const char *name)
{
struct id3_frame *frame = id3_frame_new(name);
if (v2) {
if (!n.IsAscii() || !v.IsAscii()) {
id3_field_settextencoding(id3_frame_field(frame, 0), ID3_FIELD_TEXTENCODING_UTF_16);
}
else {
id3_field_settextencoding(id3_frame_field(frame, 0), ID3_FIELD_TEXTENCODING_ISO_8859_1);
}
if (!n.IsAscii() || !v.IsAscii()) {
id3_field_settextencoding(id3_frame_field(frame, 0), ID3_FIELD_TEXTENCODING_UTF_16);
}
else {
id3_field_settextencoding(id3_frame_field(frame, 0), ID3_FIELD_TEXTENCODING_ISO_8859_1);
}
id3_ucs4_t *ucs4 =

View File

@ -302,7 +302,6 @@ void MP3ImportFileHandle::ImportID3(Tags *tags)
}
tags->Clear();
tags->SetID3V2( tp->options & ID3_TAG_OPTION_ID3V1 ? false : true );
// Loop through all frames
for (int i = 0; i < (int) tp->nframes; i++) {

View File

@ -414,8 +414,6 @@ int PCMImportFileHandle::Import(TrackFactory *trackFactory,
break;
}
tags->SetID3V2( tp->options & ID3_TAG_OPTION_ID3V1 ? false : true );
// Loop through all frames
for (int i = 0; i < (int) tp->nframes; i++) {
struct id3_frame *frame = tp->frames[i];