From 2b7863a133b221042103e6f34f29f598a90d4b7b Mon Sep 17 00:00:00 2001 From: "RichardAsh1981@gmail.com" Date: Fri, 23 Aug 2013 10:01:29 +0000 Subject: [PATCH] commit the final version of Joel Bouchat's patch for WAV and AIFF format metadata improvements --- src/Tags.h | 2 + src/export/ExportPCM.cpp | 80 ++++++++++++++++++++++++++++++---------- src/import/ImportPCM.cpp | 21 +++++++++-- src/import/ImportQT.cpp | 4 +- 4 files changed, 82 insertions(+), 25 deletions(-) diff --git a/src/Tags.h b/src/Tags.h index 10f65c29a..f3da99cd8 100644 --- a/src/Tags.h +++ b/src/Tags.h @@ -59,6 +59,8 @@ WX_DECLARE_STRING_HASH_MAP(wxString, TagMap); #define TAG_YEAR wxT("YEAR") #define TAG_GENRE wxT("GENRE") #define TAG_COMMENTS wxT("COMMENTS") +#define TAG_SOFTWARE wxT("Software") +#define TAG_COPYRIGHT wxT("Copyright") class Tags: public XMLTagHandler { diff --git a/src/export/ExportPCM.cpp b/src/export/ExportPCM.cpp index 281d58e1b..96376f291 100644 --- a/src/export/ExportPCM.cpp +++ b/src/export/ExportPCM.cpp @@ -86,7 +86,6 @@ public: ExportPCMOptions(wxWindow *parent, int format); void PopulateOrExchange(ShuttleGui & S); void OnHeaderChoice(wxCommandEvent & evt); - void OnChoice(wxCommandEvent & event); void OnOK(wxCommandEvent& event); private: @@ -323,8 +322,8 @@ public: private: - char *ConvertTo7bitASCII(wxString wxStr); - bool AddStrings(AudacityProject *project, SNDFILE *sf, Tags *tags); + char *AdjustString(wxString wxStr, int sf_format); + bool AddStrings(AudacityProject *project, SNDFILE *sf, Tags *tags, int sf_format); void AddID3Chunk(wxString fName, Tags *tags, int sf_format); }; @@ -488,9 +487,14 @@ int ExportPCM::Export(AudacityProject *project, if (metadata == NULL) metadata = project->GetTags(); - if (!AddStrings(project, sf, metadata)) { // meta data presence check - sf_close(sf); - return false; + // Install the metata at the beginning of the file (except for + // WAV and WAVEX formats) + if ((sf_format & SF_FORMAT_TYPEMASK) != SF_FORMAT_WAV && + (sf_format & SF_FORMAT_TYPEMASK) != SF_FORMAT_WAVEX) { + if (!AddStrings(project, sf, metadata, sf_format)) { + sf_close(sf); + return false; + } } sampleFormat format; @@ -557,6 +561,15 @@ int ExportPCM::Export(AudacityProject *project, delete[] waveTracks; + // Install the WAV metata in a "LIST" chunk at the end of the file + if ((sf_format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV || + (sf_format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAVEX) { + if (!AddStrings(project, sf, metadata, sf_format)) { + sf_close(sf); + return false; + } + } + ODManager::LockLibSndFileMutex(); err = sf_close(sf); ODManager::UnlockLibSndFileMutex(); @@ -570,7 +583,7 @@ int ExportPCM::Export(AudacityProject *project, buffer)); } - if (((sf_format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AIFF) || + if (((sf_format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AIFF) || ((sf_format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV)) AddID3Chunk(fName, metadata, sf_format); @@ -583,13 +596,18 @@ int ExportPCM::Export(AudacityProject *project, return updateResult; } -char *ExportPCM::ConvertTo7bitASCII(const wxString wxStr) +char *ExportPCM::AdjustString(const wxString wxStr, int sf_format) { + bool b_aiff = false; + if ((sf_format & SF_FORMAT_TYPEMASK) == SF_FORMAT_AIFF) + b_aiff = true; // Apple AIFF file + + // We must convert the string to 7 bit ASCII size_t sz = wxStr.length(); if(sz == 0) return NULL; // Size for secure malloc in case of local wide char usage - size_t sr = (sz+2) * 2; + size_t sr = (sz+4) * 2; char *pDest = (char *)malloc(sr); if (!pDest) @@ -664,21 +682,37 @@ char *ExportPCM::ConvertTo7bitASCII(const wxString wxStr) free(pSrc); + if(b_aiff) { + int len = (int)strlen(pDest); + if((len % 2) != 0) { + // In case of an odd length string, add a space char + strcat(pDest, " "); + } + } + return pDest; } -bool ExportPCM::AddStrings(AudacityProject * WXUNUSED(project), SNDFILE *sf, Tags *tags) +bool ExportPCM::AddStrings(AudacityProject * WXUNUSED(project), SNDFILE *sf, Tags *tags, int sf_format) { if (tags->HasTag(TAG_TITLE)) { - char * ascii7Str = ConvertTo7bitASCII(tags->GetTag(TAG_TITLE)); + char * ascii7Str = AdjustString(tags->GetTag(TAG_TITLE), sf_format); if (ascii7Str) { sf_set_string(sf, SF_STR_TITLE, ascii7Str); free(ascii7Str); } } + if (tags->HasTag(TAG_ALBUM)) { + char * ascii7Str = AdjustString(tags->GetTag(TAG_ALBUM), sf_format); + if (ascii7Str) { + sf_set_string(sf, SF_STR_ALBUM, ascii7Str); + free(ascii7Str); + } + } + if (tags->HasTag(TAG_ARTIST)) { - char * ascii7Str = ConvertTo7bitASCII(tags->GetTag(TAG_ARTIST)); + char * ascii7Str = AdjustString(tags->GetTag(TAG_ARTIST), sf_format); if (ascii7Str) { sf_set_string(sf, SF_STR_ARTIST, ascii7Str); free(ascii7Str); @@ -686,7 +720,7 @@ bool ExportPCM::AddStrings(AudacityProject * WXUNUSED(project), SNDFILE *sf, Tag } if (tags->HasTag(TAG_COMMENTS)) { - char * ascii7Str = ConvertTo7bitASCII(tags->GetTag(TAG_COMMENTS)); + char * ascii7Str = AdjustString(tags->GetTag(TAG_COMMENTS), sf_format); if (ascii7Str) { sf_set_string(sf, SF_STR_COMMENT, ascii7Str); free(ascii7Str); @@ -694,7 +728,7 @@ bool ExportPCM::AddStrings(AudacityProject * WXUNUSED(project), SNDFILE *sf, Tag } if (tags->HasTag(TAG_YEAR)) { - char * ascii7Str = ConvertTo7bitASCII(tags->GetTag(TAG_YEAR)); + char * ascii7Str = AdjustString(tags->GetTag(TAG_YEAR), sf_format); if (ascii7Str) { sf_set_string(sf, SF_STR_DATE, ascii7Str); free(ascii7Str); @@ -702,29 +736,37 @@ bool ExportPCM::AddStrings(AudacityProject * WXUNUSED(project), SNDFILE *sf, Tag } if (tags->HasTag(TAG_GENRE)) { - char * ascii7Str = ConvertTo7bitASCII(tags->GetTag(TAG_GENRE)); + char * ascii7Str = AdjustString(tags->GetTag(TAG_GENRE), sf_format); if (ascii7Str) { sf_set_string(sf, SF_STR_GENRE, ascii7Str); free(ascii7Str); } } - if (tags->HasTag(wxT("Copyright"))) { - char * ascii7Str = ConvertTo7bitASCII(tags->GetTag(wxT("Copyright"))); + if (tags->HasTag(TAG_COPYRIGHT)) { + char * ascii7Str = AdjustString(tags->GetTag(TAG_COPYRIGHT), sf_format); if (ascii7Str) { sf_set_string(sf, SF_STR_COPYRIGHT, ascii7Str); free(ascii7Str); } } - if (tags->HasTag(wxT("Software"))) { - char * ascii7Str = ConvertTo7bitASCII(tags->GetTag(wxT("Software"))); + if (tags->HasTag(TAG_SOFTWARE)) { + char * ascii7Str = AdjustString(tags->GetTag(TAG_SOFTWARE), sf_format); if (ascii7Str) { sf_set_string(sf, SF_STR_SOFTWARE, ascii7Str); free(ascii7Str); } } + if (tags->HasTag(TAG_TRACK)) { + char * ascii7Str = AdjustString(tags->GetTag(TAG_TRACK), sf_format); + if (ascii7Str) { + sf_set_string(sf, SF_STR_TRACKNUMBER, ascii7Str); + free(ascii7Str); + } + } + return true; } diff --git a/src/import/ImportPCM.cpp b/src/import/ImportPCM.cpp index 65adf92c6..07bfb48d8 100644 --- a/src/import/ImportPCM.cpp +++ b/src/import/ImportPCM.cpp @@ -480,6 +480,11 @@ int PCMImportFileHandle::Import(TrackFactory *trackFactory, tags->SetTag(TAG_TITLE, UTF8CTOWX(str)); } + str = sf_get_string(mFile, SF_STR_ALBUM); + if (str) { + tags->SetTag(TAG_ALBUM, UTF8CTOWX(str)); + } + str = sf_get_string(mFile, SF_STR_ARTIST); if (str) { tags->SetTag(TAG_ARTIST, UTF8CTOWX(str)); @@ -497,12 +502,22 @@ int PCMImportFileHandle::Import(TrackFactory *trackFactory, str = sf_get_string(mFile, SF_STR_COPYRIGHT); if (str) { - tags->SetTag(wxT("Copyright"), UTF8CTOWX(str)); + tags->SetTag(TAG_COPYRIGHT, UTF8CTOWX(str)); } str = sf_get_string(mFile, SF_STR_SOFTWARE); if (str) { - tags->SetTag(wxT("Software"), UTF8CTOWX(str)); + tags->SetTag(TAG_SOFTWARE, UTF8CTOWX(str)); + } + + str = sf_get_string(mFile, SF_STR_TRACKNUMBER); + if (str) { + tags->SetTag(TAG_TRACK, UTF8CTOWX(str)); + } + + str = sf_get_string(mFile, SF_STR_GENRE); + if (str) { + tags->SetTag(TAG_GENRE, UTF8CTOWX(str)); } #if defined(USE_LIBID3TAG) @@ -655,5 +670,3 @@ PCMImportFileHandle::~PCMImportFileHandle() { sf_close(mFile); } - - diff --git a/src/import/ImportQT.cpp b/src/import/ImportQT.cpp index 906890e6a..3cf3223e0 100644 --- a/src/import/ImportQT.cpp +++ b/src/import/ImportQT.cpp @@ -412,7 +412,7 @@ names[] = { { kQTMetaDataCommonKeyAuthor, wxT("Author") }, { kQTMetaDataCommonKeyComment, TAG_COMMENTS }, - { kQTMetaDataCommonKeyCopyright, wxT("Copyright") }, + { kQTMetaDataCommonKeyCopyright, TAG_COPYRIGHT }, { kQTMetaDataCommonKeyDirector, wxT("Director") }, { kQTMetaDataCommonKeyDisplayName, wxT("Full Name") }, { kQTMetaDataCommonKeyInformation, wxT("Information") }, @@ -427,7 +427,7 @@ names[] = { kQTMetaDataCommonKeyOriginalFormat, wxT("Original Format") }, { kQTMetaDataCommonKeyOriginalSource, wxT("Original Source") }, { kQTMetaDataCommonKeyPerformers, wxT("Performers") }, - { kQTMetaDataCommonKeySoftware, wxT("Software") }, + { kQTMetaDataCommonKeySoftware, TAG_SOFTWARE }, { kQTMetaDataCommonKeyWriter, wxT("Writer") }, };