Git commit 59867f7b1a5214664d256db5d7b91972b63794dd by Thomas Eschenbacher, on behalf of Thomas Eschenbacher. Committed on 29/08/2026 at 16:53. Pushed by eschenbacher into branch 'master'.
finished migration from id3lib to taglib M +1 -42 .flatpak-manifest.json D +0 -14 .flatpak-patches/00-add-libz-to-compilation.patch D +0 -12 .flatpak-patches/05-create-m4-directory.patch D +0 -22 .flatpak-patches/10-fix-compilation-with-cpp-headers.patch D +0 -45 .flatpak-patches/15-fix-headers-of-main-functions.patch D +0 -38 .flatpak-patches/30-fix-utf16.patch D +0 -24 .flatpak-patches/31-fix-utf16-stringlists.patch D +0 -54 .flatpak-patches/40-deal-with-mkstemp.patch D +0 -21 .flatpak-patches/50-remove-outdated-check.patch D +0 -58 .flatpak-patches/60-add-c-wrapper-functions.patch D +0 -50 .flatpak-patches/60-fix_make_check.patch D +0 -12 .flatpak-patches/60-id3lib-missing-nullpointer-check.patch D +0 -19 .flatpak-patches/61-fix_vbr_stack_smash.patch D +0 -32 .flatpak-patches/62-remove-remote-icons.patch D +0 -4 .flatpak-patches/README D +0 -55 .flatpak-patches/copyright M +3 -1 CHANGES M +2 -8 LICENSES M +10 -8 TODO M +0 -3 doc/devel.docbook M +0 -5 kwave/main.cpp M +1 -23 plugins/codec_mp3/CMakeLists.txt D +0 -321 plugins/codec_mp3/ID3_PropertyMap.cpp D +0 -130 plugins/codec_mp3/ID3_PropertyMap.h D +0 -103 plugins/codec_mp3/ID3_QIODeviceReader.cpp D +0 -82 plugins/codec_mp3/ID3_QIODeviceReader.h D +0 -100 plugins/codec_mp3/ID3_QIODeviceWriter.cpp D +0 -93 plugins/codec_mp3/ID3_QIODeviceWriter.h M +232 -195 plugins/codec_mp3/MP3Encoder.cpp M +6 -4 plugins/codec_mp3/MP3Encoder.h https://invent.kde.org/multimedia/kwave/-/commit/59867f7b1a5214664d256db5d7b91972b63794dd diff --git a/.flatpak-manifest.json b/.flatpak-manifest.json index 5bca9d2c..37b16016 100644 --- a/.flatpak-manifest.json +++ b/.flatpak-manifest.json @@ -40,47 +40,6 @@ "/bin" ] }, - { - "name": "id3lib", - "buildsystem": "autotools", - "config-opts": [ - "--disable-static" - ], - "sources": [ - { - "type": "archive", - "url": "http://downloads.sourceforge.net/id3lib/id3lib-3.8.3.tar.gz", - "sha256": "2749cc3c0cd7280b299518b1ddf5a5bcfe2d1100614519b68702230e26c7d079" - }, - { - "type": "patch", - "paths": [ - ".flatpak-patches/00-add-libz-to-compilation.patch", - ".flatpak-patches/05-create-m4-directory.patch", - ".flatpak-patches/10-fix-compilation-with-cpp-headers.patch", - ".flatpak-patches/15-fix-headers-of-main-functions.patch", - ".flatpak-patches/30-fix-utf16.patch", - ".flatpak-patches/31-fix-utf16-stringlists.patch", - ".flatpak-patches/40-deal-with-mkstemp.patch", - ".flatpak-patches/50-remove-outdated-check.patch", - ".flatpak-patches/60-add-c-wrapper-functions.patch", - ".flatpak-patches/60-fix_make_check.patch", - ".flatpak-patches/60-id3lib-missing-nullpointer-check.patch", - ".flatpak-patches/61-fix_vbr_stack_smash.patch", - ".flatpak-patches/62-remove-remote-icons.patch" - ] - }, - { - "type": "shell", - "commands": [ - "cp -p /usr/share/automake-*/config.{sub,guess} ." - ] - } - ], - "cleanup": [ - "/bin" - ] - }, { "name": "libmad", "buildsystem": "cmake-ninja", @@ -103,7 +62,7 @@ { "type": "archive", "url": "https://taglib.github.io/releases/taglib-2.0.2.tar.gz", - "sha256": "43242202ed726618764010375f4d80a1a0f82d259c63c32e541459a0d24ee312" + "sha256": "0de288d7fe34ba133199fd8512f19cc1100196826eafcb67a33b224ec3a59737" } ] }, diff --git a/.flatpak-patches/00-add-libz-to-compilation.patch b/.flatpak-patches/00-add-libz-to-compilation.patch deleted file mode 100644 index e9378773..00000000 --- a/.flatpak-patches/00-add-libz-to-compilation.patch +++ /dev/null @@ -1,14 +0,0 @@ -This patch was first introduced in version 3.8.3-3 - -It fixes http://bugs.debian.org/208672 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -74,6 +74,8 @@ - - if ID3_NEEDZLIB - LDADD = $(top_builddir)/zlib/src/libz.la -+else -+libid3_la_LIBADD = -lz - endif - - libid3_la_LDFLAGS = \ diff --git a/.flatpak-patches/05-create-m4-directory.patch b/.flatpak-patches/05-create-m4-directory.patch deleted file mode 100644 index d8111205..00000000 --- a/.flatpak-patches/05-create-m4-directory.patch +++ /dev/null @@ -1,12 +0,0 @@ -Create a local m4 subdirectory ---- a/Makefile.am -+++ b/Makefile.am -@@ -12,6 +12,8 @@ - # require automake 1.5 - AUTOMAKE_OPTIONS = 1.5 - -+ACLOCAL_AMFLAGS = -I m4 -+ - EXTRA_DIST = \ - HISTORY \ - config.h.win32 \ diff --git a/.flatpak-patches/10-fix-compilation-with-cpp-headers.patch b/.flatpak-patches/10-fix-compilation-with-cpp-headers.patch deleted file mode 100644 index a9b45ab0..00000000 --- a/.flatpak-patches/10-fix-compilation-with-cpp-headers.patch +++ /dev/null @@ -1,22 +0,0 @@ -This patch imports the proper C++ headers ---- a/include/id3/id3lib_strings.h -+++ b/include/id3/id3lib_strings.h -@@ -30,6 +30,7 @@ - #define _ID3LIB_STRINGS_H_ - - #include <string> -+#include <cstring> - - #if (defined(__GNUC__) && (__GNUC__ >= 3) || (defined(_MSC_VER) && _MSC_VER > 1000)) - namespace std ---- a/include/id3/writers.h -+++ b/include/id3/writers.h -@@ -30,7 +30,7 @@ - - #include "id3/writer.h" - #include "id3/id3lib_streams.h" --//#include <string.h> -+#include <cstring> - - class ID3_CPP_EXPORT ID3_OStreamWriter : public ID3_Writer - { diff --git a/.flatpak-patches/15-fix-headers-of-main-functions.patch b/.flatpak-patches/15-fix-headers-of-main-functions.patch deleted file mode 100644 index 48e01d14..00000000 --- a/.flatpak-patches/15-fix-headers-of-main-functions.patch +++ /dev/null @@ -1,45 +0,0 @@ -This patch fixes some function headers in demo code used during 'make check' ---- a/examples/demo_info.cpp -+++ b/examples/demo_info.cpp -@@ -309,7 +309,7 @@ - - #define DEBUG - --int main( unsigned int argc, char * const argv[]) -+int main(int argc, char * const argv[]) - { - ID3D_INIT_DOUT(); - ---- a/examples/demo_convert.cpp -+++ b/examples/demo_convert.cpp -@@ -84,7 +84,7 @@ - } - } - --int main( unsigned int argc, char * const argv[]) -+int main(int argc, char * const argv[]) - { - flags_t ulFlag = ID3TT_ALL; - gengetopt_args_info args; ---- a/examples/demo_copy.cpp -+++ b/examples/demo_copy.cpp -@@ -81,7 +81,7 @@ - } - } - --int main( unsigned int argc, char * const argv[]) -+int main(int argc, char * const argv[]) - { - int ulFlag = ID3TT_ID3; - ID3D_INIT_DOUT(); ---- a/examples/demo_tag.cpp -+++ b/examples/demo_tag.cpp -@@ -46,7 +46,7 @@ - os << "v2"; - } - --int main( unsigned int argc, char * const argv[]) -+int main(int argc, char * const argv[]) - { - int ulFlag = ID3TT_ID3; - ID3D_INIT_DOUT(); diff --git a/.flatpak-patches/30-fix-utf16.patch b/.flatpak-patches/30-fix-utf16.patch deleted file mode 100644 index 3d3f50fe..00000000 --- a/.flatpak-patches/30-fix-utf16.patch +++ /dev/null @@ -1,38 +0,0 @@ -Patch from 'Spoon' to fix issues with writing certain unicode characters ---- a/ChangeLog -+++ b/ChangeLog -@@ -1,3 +1,8 @@ -+2006-02-17 Jerome Couderc -+ -+ * Patch from Spoon to fix UTF-16 writing bug -+ http://sourceforge.net/tracker/index.php?func=detail&aid=1016290&group_id=979&atid=300979 -+ - 2003-03-02 Sunday 17:38 Thijmen Klok <[email protected]> - - * THANKS (1.20): added more people ---- a/src/io_helpers.cpp -+++ b/src/io_helpers.cpp -@@ -363,11 +363,22 @@ - // Write the BOM: 0xFEFF - unicode_t BOM = 0xFEFF; - writer.writeChars((const unsigned char*) &BOM, 2); -+ // Patch from Spoon : 2004-08-25 14:17 -+ // http://sourceforge.net/tracker/index.php?func=detail&aid=1016290&group_id=979&atid=300979 -+ // Wrong code -+ //for (size_t i = 0; i < size; i += 2) -+ //{ -+ // unicode_t ch = (data[i] << 8) | data[i+1]; -+ // writer.writeChars((const unsigned char*) &ch, 2); -+ //} -+ // Right code -+ unsigned char *pdata = (unsigned char *) data.c_str(); - for (size_t i = 0; i < size; i += 2) - { -- unicode_t ch = (data[i] << 8) | data[i+1]; -+ unicode_t ch = (pdata[i] << 8) | pdata[i+1]; - writer.writeChars((const unsigned char*) &ch, 2); - } -+ // End patch - } - return writer.getCur() - beg; - } diff --git a/.flatpak-patches/31-fix-utf16-stringlists.patch b/.flatpak-patches/31-fix-utf16-stringlists.patch deleted file mode 100644 index 35822387..00000000 --- a/.flatpak-patches/31-fix-utf16-stringlists.patch +++ /dev/null @@ -1,24 +0,0 @@ -This patch fixes tag corruption after pipe characters. - -Author: Urs Fleisch <[email protected]> -Fixes: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=680915 ---- a/src/io_helpers.cpp -+++ b/src/io_helpers.cpp -@@ -373,10 +373,17 @@ - //} - // Right code - unsigned char *pdata = (unsigned char *) data.c_str(); -+ unicode_t lastCh = BOM; - for (size_t i = 0; i < size; i += 2) - { - unicode_t ch = (pdata[i] << 8) | pdata[i+1]; -+ if (lastCh == 0 && ch != BOM) -+ { -+ // Last character was NULL, so start next string with BOM. -+ writer.writeChars((const unsigned char*) &BOM, 2); -+ } - writer.writeChars((const unsigned char*) &ch, 2); -+ lastCh = ch; - } - // End patch - } diff --git a/.flatpak-patches/40-deal-with-mkstemp.patch b/.flatpak-patches/40-deal-with-mkstemp.patch deleted file mode 100644 index 36c84179..00000000 --- a/.flatpak-patches/40-deal-with-mkstemp.patch +++ /dev/null @@ -1,54 +0,0 @@ -This patch fixes an issues where temporary files were created in an insecure -way. - -It was first intruduced in version 3.8.3-7 and fixes -http://bugs.debian.org/438540 ---- a/src/tag_file.cpp -+++ b/src/tag_file.cpp -@@ -242,8 +242,8 @@ - strcpy(sTempFile, filename.c_str()); - strcat(sTempFile, sTmpSuffix.c_str()); - --#if ((defined(__GNUC__) && __GNUC__ >= 3 ) || !defined(HAVE_MKSTEMP)) -- // This section is for Windows folk && gcc 3.x folk -+#if !defined(HAVE_MKSTEMP) -+ // This section is for Windows folk - fstream tmpOut; - createFile(sTempFile, tmpOut); - -@@ -257,7 +257,7 @@ - tmpOut.write((char *)tmpBuffer, nBytes); - } - --#else //((defined(__GNUC__) && __GNUC__ >= 3 ) || !defined(HAVE_MKSTEMP)) -+#else //!defined(HAVE_MKSTEMP) - - // else we gotta make a temp file, copy the tag into it, copy the - // rest of the old file after the tag, delete the old file, rename -@@ -270,7 +270,7 @@ - //ID3_THROW_DESC(ID3E_NoFile, "couldn't open temp file"); - } - -- ofstream tmpOut(fd); -+ ofstream tmpOut(sTempFile); - if (!tmpOut) - { - tmpOut.close(); -@@ -285,14 +285,14 @@ - uchar tmpBuffer[BUFSIZ]; - while (file) - { -- file.read(tmpBuffer, BUFSIZ); -+ file.read((char *)tmpBuffer, BUFSIZ); - size_t nBytes = file.gcount(); -- tmpOut.write(tmpBuffer, nBytes); -+ tmpOut.write((char *)tmpBuffer, nBytes); - } - - close(fd); //closes the file - --#endif ////((defined(__GNUC__) && __GNUC__ >= 3 ) || !defined(HAVE_MKSTEMP)) -+#endif ////!defined(HAVE_MKSTEMP) - - tmpOut.close(); - file.close(); diff --git a/.flatpak-patches/50-remove-outdated-check.patch b/.flatpak-patches/50-remove-outdated-check.patch deleted file mode 100644 index b1c33d78..00000000 --- a/.flatpak-patches/50-remove-outdated-check.patch +++ /dev/null @@ -1,21 +0,0 @@ -We don't actually need iomanip.h ---- a/configure.in -+++ b/configure.in -@@ -227,7 +227,6 @@ - ) - AC_CHECK_HEADERS( \ - string \ -- iomanip.h \ - ,,AC_MSG_ERROR([Missing a vital header file for id3lib]) - ) - ---- a/configure -+++ b/configure -@@ -10296,7 +10296,6 @@ - - for ac_header in \ - string \ -- iomanip.h \ - - do - as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` diff --git a/.flatpak-patches/60-add-c-wrapper-functions.patch b/.flatpak-patches/60-add-c-wrapper-functions.patch deleted file mode 100644 index d72e81c0..00000000 --- a/.flatpak-patches/60-add-c-wrapper-functions.patch +++ /dev/null @@ -1,58 +0,0 @@ -This patch adds C wrapper functions for field encoding. - -It was first introduced in version 3.8.3-8 and fixes -http://bugs.debian.org/281292 ---- a/include/id3.h -+++ b/include/id3.h -@@ -104,6 +104,9 @@ - ID3_C_EXPORT void CCONV ID3Field_GetBINARY (const ID3Field *field, uchar *buffer, size_t buffLength); - ID3_C_EXPORT void CCONV ID3Field_FromFile (ID3Field *field, const char *fileName); - ID3_C_EXPORT void CCONV ID3Field_ToFile (const ID3Field *field, const char *fileName); -+ ID3_C_EXPORT bool CCONV ID3Field_SetEncoding (ID3Field *field, ID3_TextEnc enc); -+ ID3_C_EXPORT ID3_TextEnc CCONV ID3Field_GetEncoding (const ID3Field *field); -+ ID3_C_EXPORT bool CCONV ID3Field_IsEncodable (const ID3Field *field); - - /* field-info wrappers */ - ID3_C_EXPORT char* CCONV ID3FrameInfo_ShortName (ID3_FrameID frameid); ---- a/src/c_wrapper.cpp -+++ b/src/c_wrapper.cpp -@@ -681,6 +681,39 @@ - } - } - -+ ID3_C_EXPORT bool CCONV -+ ID3Field_SetEncoding(ID3Field *field, ID3_TextEnc enc) -+ { -+ bool changed = false; -+ if (field) -+ { -+ ID3_CATCH(changed = reinterpret_cast<ID3_Field *>(field)->SetEncoding(enc)); -+ } -+ return changed; -+ } -+ -+ ID3_C_EXPORT ID3_TextEnc CCONV -+ ID3Field_GetEncoding(const ID3Field *field) -+ { -+ ID3_TextEnc enc = ID3TE_NONE; -+ if (field) -+ { -+ ID3_CATCH(enc = reinterpret_cast<const ID3_Field *>(field)->GetEncoding()); -+ } -+ return enc; -+ } -+ -+ ID3_C_EXPORT bool CCONV -+ ID3Field_IsEncodable(const ID3Field *field) -+ { -+ bool isEncodable = false; -+ if (field) -+ { -+ ID3_CATCH(isEncodable = reinterpret_cast<const ID3_Field *>(field)->IsEncodable()); -+ } -+ return isEncodable; -+ } -+ - #ifdef __cplusplus - } - #endif /* __cplusplus */ diff --git a/.flatpak-patches/60-fix_make_check.patch b/.flatpak-patches/60-fix_make_check.patch deleted file mode 100644 index e2bb1b05..00000000 --- a/.flatpak-patches/60-fix_make_check.patch +++ /dev/null @@ -1,50 +0,0 @@ -This patch fixes some function headers and imports in order for 'make check' -to work. - -It was first introduced in version 3.8.3-9 -diff -Naur id3lib-3.8.3.orig/examples/findeng.cpp id3lib-3.8.3/examples/findeng.cpp ---- id3lib-3.8.3.orig/examples/findeng.cpp 2003-03-02 01:23:00.000000000 +0100 -+++ id3lib-3.8.3/examples/findeng.cpp 2009-12-10 00:58:12.173795997 +0100 -@@ -9,7 +9,7 @@ - using std::cout; - using std::endl; - --int main(unsigned argc, char* argv[]) -+int main(int argc, char* argv[]) - { - ID3D_INIT_DOUT(); - ID3D_INIT_WARNING(); -diff -Naur id3lib-3.8.3.orig/examples/findstr.cpp id3lib-3.8.3/examples/findstr.cpp ---- id3lib-3.8.3.orig/examples/findstr.cpp 2003-03-02 01:23:00.000000000 +0100 -+++ id3lib-3.8.3/examples/findstr.cpp 2009-12-10 00:57:48.036819825 +0100 -@@ -9,7 +9,7 @@ - using std::cout; - using std::endl; - --int main(unsigned argc, char* argv[]) -+int main(int argc, char* argv[]) - { - ID3D_INIT_DOUT(); - ID3D_INIT_WARNING(); -diff -Naur id3lib-3.8.3.orig/examples/test_io.cpp id3lib-3.8.3/examples/test_io.cpp ---- id3lib-3.8.3.orig/examples/test_io.cpp 2003-03-02 01:23:00.000000000 +0100 -+++ id3lib-3.8.3/examples/test_io.cpp 2009-12-10 00:57:03.612111640 +0100 -@@ -11,6 +11,9 @@ - #include <id3/io_strings.h> - #include <id3/utils.h> - -+using std::cin; -+using std::hex; -+using std::dec; - using std::cout; - using std::endl; - using std::cerr; -@@ -18,7 +21,7 @@ - using namespace dami; - - int --main(size_t argc, const char** argv) -+main(int argc, const char** argv) - { - ID3D_INIT_DOUT(); - ID3D_INIT_WARNING(); diff --git a/.flatpak-patches/60-id3lib-missing-nullpointer-check.patch b/.flatpak-patches/60-id3lib-missing-nullpointer-check.patch deleted file mode 100644 index d4ca5d29..00000000 --- a/.flatpak-patches/60-id3lib-missing-nullpointer-check.patch +++ /dev/null @@ -1,12 +0,0 @@ -This patch adds a check for a null pointer ---- a/src/header_tag.cpp -+++ b/src/header_tag.cpp -@@ -54,7 +54,7 @@ - { - size_t bytesUsed = ID3_TagHeader::SIZE; - -- if (_info->is_extended) -+ if (_info && _info->is_extended) - { - bytesUsed += _info->extended_bytes; - } diff --git a/.flatpak-patches/61-fix_vbr_stack_smash.patch b/.flatpak-patches/61-fix_vbr_stack_smash.patch deleted file mode 100644 index 9bf33e97..00000000 --- a/.flatpak-patches/61-fix_vbr_stack_smash.patch +++ /dev/null @@ -1,19 +0,0 @@ -Description: Fix crashes when reading VBR MP3 file. -Bug-Ubuntu: https://launchpad.net/bugs/444466 -Origin: upstream, http://sourceforge.net/tracker/?func=detail&aid=937707&group_id=979&atid=300979 -Forwarded: yes -Author: Urs Fleisch - -Index: id3lib3.8.3-3.8.3/src/mp3_parse.cpp -=================================================================== ---- id3lib3.8.3-3.8.3.orig/src/mp3_parse.cpp 2009-10-06 23:12:10.381250132 +0200 -+++ id3lib3.8.3-3.8.3/src/mp3_parse.cpp 2009-10-06 23:14:09.545252591 +0200 -@@ -465,7 +465,7 @@ - // from http://www.xingtech.com/developer/mp3/ - - const size_t VBR_HEADER_MIN_SIZE = 8; // "xing" + flags are fixed -- const size_t VBR_HEADER_MAX_SIZE = 116; // frames, bytes, toc and scale are optional -+ const size_t VBR_HEADER_MAX_SIZE = 120; // frames, bytes, toc and scale are optional - - if (mp3size >= vbr_header_offest + VBR_HEADER_MIN_SIZE) - { diff --git a/.flatpak-patches/62-remove-remote-icons.patch b/.flatpak-patches/62-remove-remote-icons.patch deleted file mode 100644 index 6d929953..00000000 --- a/.flatpak-patches/62-remove-remote-icons.patch +++ /dev/null @@ -1,32 +0,0 @@ -This patch removes two icons from the documentation which would be loaded from -remote servers, thereby exposing the reader's IP address to potential tracking -(lintian keywords privacy-breach-logo and privacy-breach-w3c-valid-html). - -Author: Stefan Ott <[email protected]> ---- a/doc/index.html -+++ b/doc/index.html -@@ -427,24 +427,5 @@ - </td> - </tr> - </table> -- -- <br><br> -- -- <table align="center" width="80%" border="0"> -- <tr> -- <td align="left"> -- <a href="http://sourceforge.net"> -- <IMG src="http://sourceforge.net/sflogo.php?group_id=979&type=1" width="88" height="31" border="0" alt="SourceForge.net"></A> -- </td> -- <td align="right"> -- -- <a href="http://validator.w3.org/check/referer"> -- <img border=0 -- src="http://validator.w3.org/images/vh401" -- alt="Valid HTML 4.01!" height=31 width=88></a> -- </td> -- </tr> -- </table> -- <br> - </body> - </html> diff --git a/.flatpak-patches/README b/.flatpak-patches/README deleted file mode 100644 index ee039d27..00000000 --- a/.flatpak-patches/README +++ /dev/null @@ -1,4 +0,0 @@ -These patches are only used when building a flatpak. id3lib is unmaintained, so these patches are needed to build it. - -id3lib patches downloaded from https://sources.debian.org/src/id3lib3.8.3/3.8.3-18/debian/patches/ -copyright file downloaded from https://sources.debian.org/src/id3lib3.8.3/3.8.3-18/debian/copyright/ diff --git a/.flatpak-patches/copyright b/.flatpak-patches/copyright deleted file mode 100644 index f2c72991..00000000 --- a/.flatpak-patches/copyright +++ /dev/null @@ -1,55 +0,0 @@ -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: id3lib -Source: http://id3lib.sourceforge.net/ - -Files: * -Copyright: Copyright 1999, 2000, Scott Thomas Haug <[email protected]> -License: LGPL-2+ - id3lib: a C++ library for creating and manipulating id3v1/v2 tags - Copyright 1999, 2000 Scott Thomas Haug - . - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - . - This library is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public - License for more details. - . - You should have received a copy of the GNU Library General Public License - along with this library; if not, write to the Free Software Foundation, - Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - . - The id3lib authors encourage improvements and optimisations to be sent to - the id3lib coordinator. Please see the README file for details on where to - send such submissions. See the AUTHORS file for a list of people who have - contributed to id3lib. See the ChangeLog file for a list of changes to - id3lib. These files are distributed with id3lib at - http://download.sourceforge.net/id3lib/ - . - On Debian systems, the full text of the GNU Library General Public - License version 2 can be found in the file - `/usr/share/common-licenses/LGPL-2'. - -Files: debian/* -Copyright: 2009-2014, Stefan Ott <[email protected]> -License: GPL-2+ - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - . - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - . - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - . - On Debian systems, the full text of the GNU Library General Public - License version 2 can be found in the file - `/usr/share/common-licenses/GPL-2'. diff --git a/CHANGES b/CHANGES index 979c922e..f1d67dee 100644 --- a/CHANGES +++ b/CHANGES @@ -6,7 +6,9 @@ - implemented encoder, adding support for saving in many legacy formats, including meta data and cue lists (as far as supported by libaudiofile) * codec_flac: parallelized decoding + added check for > 8 channels - * codec_mp3: workaround for broken MBS conversion in ID3LIB + * codec_mp3: + - workaround for broken MBS conversion in ID3LIB + - migrated from id3lib to taglib * codec_mp3: do no longer explicitly link against libstdc++ and libz * codec_ogg: parallelized decoding of ogg/opus and ogg/vorbis * codec_ogg: support for up to 255 channels for ogg/opus and ogg/vorbis diff --git a/LICENSES b/LICENSES index a02e05c2..6c47ca49 100644 --- a/LICENSES +++ b/LICENSES @@ -43,8 +43,8 @@ DIRECTLY USED EXTERNAL LIBRARIES * KDE frameworks LGPL2 * FFTW-3 GPL2+ * audiofile LGPL2+ / GPL2+ - * id3lib LGPL2.1 - * mad GPL2+ <= possible patent issue !!! + * taglib LGPL2.1/MPL1.1 + * mad GPL2+ * ogg ~BSD style * flac Xiph.Org's BSD-like + GPL2 + LGPL2 * alsa-lib LGPL2.1 @@ -539,12 +539,6 @@ COMPLETE LIST OF FILES AND THEIR LICENSE plugins/codec_flac/kwaveplugin_codec_flac.json.in (UNKNOWN) plugins/codec_mp3/CMakeLists.txt BSD (3 clause) - plugins/codec_mp3/ID3_PropertyMap.cpp GPL2+ - plugins/codec_mp3/ID3_PropertyMap.h GPL2+ - plugins/codec_mp3/ID3_QIODeviceReader.cpp GPL2+ - plugins/codec_mp3/ID3_QIODeviceReader.h GPL2+ - plugins/codec_mp3/ID3_QIODeviceWriter.cpp GPL2+ - plugins/codec_mp3/ID3_QIODeviceWriter.h GPL2+ plugins/codec_mp3/kwaveplugin_codec_mp3.json.in (UNKNOWN) plugins/codec_mp3/MP3CodecPlugin.cpp GPL2+ plugins/codec_mp3/MP3CodecPlugin.h GPL2+ diff --git a/TODO b/TODO index 2402dba4..486938aa 100644 --- a/TODO +++ b/TODO @@ -1,4 +1,13 @@ +o migrate MP3 import from libmad to libmpg123 + +o use libmp3lame natively for MP3 export + +o migrate from libaudiofile to libsndfile + +o FileInfo dialog: consequently disable properties which are not + supported by encoder + o collapse/expand of track views o add views with meta data @@ -25,7 +34,7 @@ o FLAC in Ogg container o SPEEX in Ogg container -o ALAC support (via libaudiofile) +o ALAC support o codec_wav: disable workaround for fact chunk == 0 as soon as a newer version of libaudiofile is available which can handle this @@ -143,13 +152,6 @@ o user selectable color scheme o re-evaluate use of taglib as alternative to id3lib -o port from id3lib to taglib - => rejected, currently no alternative available - => taglib currently works only on files, unsuitable API - + inaccurate file length detection (units of 1 sec) - => libid3tag is nearly as old, undocumented and would - produce a lot of work - o switch to use float as sample_t (requires much work...) -> version 0.9.x diff --git a/doc/devel.docbook b/doc/devel.docbook index cf2ad9b1..23c2ecad 100644 --- a/doc/devel.docbook +++ b/doc/devel.docbook @@ -158,9 +158,6 @@ <listitem><para> PulseAudio 4.0 or higher (for record/playback) </para></listitem> - <listitem><para> - id3lib-3.8.1 or higher (for ID3 tags) - </para></listitem> <listitem><para> mad-0.15 or higher (optionally for MP3 import/export) </para></listitem> diff --git a/kwave/main.cpp b/kwave/main.cpp index 88fa1bc0..c39a1469 100644 --- a/kwave/main.cpp +++ b/kwave/main.cpp @@ -116,11 +116,6 @@ static void addDataStrings(KAboutData &aboutdata) i18n("Author of the 'mad' MP3 decoder library"), _("[email protected]"), i18n("http://www.mars.org/home/rob/proj/mpeg")); - aboutdata.addCredit( - i18n("T.H.F. Klok and Cedric Tefft"), - i18n("Maintainers of the 'id3lib' library"), - QString(), - i18n("http://www.id3lib.org/")); aboutdata.addCredit( i18n("Michael Pruett"), i18n("Author of the 'audiofile' library"), diff --git a/plugins/codec_mp3/CMakeLists.txt b/plugins/codec_mp3/CMakeLists.txt index 33cdbd00..ca229eba 100644 --- a/plugins/codec_mp3/CMakeLists.txt +++ b/plugins/codec_mp3/CMakeLists.txt @@ -30,9 +30,6 @@ IF (WITH_MP3) PKG_CHECK_MODULES(MADLIB REQUIRED mad>=0.15.0) PKG_CHECK_MODULES(TAGLIB REQUIRED taglib>=2.0) - ### TODO legacy ### - find_library(ID3LIB NAMES id3 REQUIRED) - SET(HAVE_MP3 ON CACHE BOOL "enable MP3 codec") INCLUDE_DIRECTORIES( @@ -46,9 +43,6 @@ IF (WITH_MP3) ) SET(plugin_codec_mp3_LIB_SRCS - ID3_PropertyMap.cpp - ID3_QIODeviceReader.cpp ### TODO legacy ### - ID3_QIODeviceWriter.cpp ### TODO legacy ### MP3CodecPlugin.cpp MP3Decoder.cpp MP3Encoder.cpp @@ -56,9 +50,6 @@ IF (WITH_MP3) MP3EncoderSettings.cpp TagLib_PropertyMap.cpp - ID3_PropertyMap.h - ID3_QIODeviceReader.h ### TODO legacy ### - ID3_QIODeviceWriter.h ### TODO legacy ### MP3CodecPlugin.h MP3Decoder.h MP3Encoder.h @@ -73,22 +64,9 @@ IF (WITH_MP3) ) SET(plugin_codec_mp3_LIBS - ${MADLIB_LIBRARIES} ${ID3LIB} ${TAGLIB_LIBRARIES} + ${MADLIB_LIBRARIES} ${TAGLIB_LIBRARIES} ) - ### TODO legacy ### - INCLUDE(CheckCXXCompilerFlag) - CHECK_CXX_COMPILER_FLAG("-Wno-non-virtual-dtor" HAVE_WNO_NON_VIRTUAL_DTOR) - IF (HAVE_WNO_NON_VIRTUAL_DTOR) - SET_SOURCE_FILES_PROPERTIES( - MP3Decoder.cpp - MP3Encoder.cpp - ID3_QIODeviceReader.cpp - ID3_QIODeviceWriter.cpp - PROPERTIES COMPILE_FLAGS "-Wno-non-virtual-dtor" - ) - ENDIF (HAVE_WNO_NON_VIRTUAL_DTOR) - KWAVE_PLUGIN(codec_mp3) ENDIF (WITH_MP3) diff --git a/plugins/codec_mp3/ID3_PropertyMap.cpp b/plugins/codec_mp3/ID3_PropertyMap.cpp deleted file mode 100644 index 28e34228..00000000 --- a/plugins/codec_mp3/ID3_PropertyMap.cpp +++ /dev/null @@ -1,321 +0,0 @@ -/************************************************************************* - ID3_PropertyMap.cpp - map for translating properties to ID3 frame tags - ------------------- - begin : Sat Jul 30 2012 - copyright : (C) 2012 by Thomas Eschenbacher - email : [email protected] - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#include "config.h" - -#include <id3/field.h> - -#include "ID3_PropertyMap.h" - -//*************************************************************************** -Kwave::ID3_PropertyMap::ID3_PropertyMap() - :m_list() -{ - // NOTE #1: the first column is allowed to have multiple entries with the - // same property, when encoding the first one is used, when - // decoding, the other ones serve as alternatives - // NOTE #2: the ID3 tag names in the secondt column must be *unique* ! - - // Album/Movie/Show title - insert(Kwave::INF_ALBUM, ID3FID_ALBUM, - ENC_TEXT); - // Original album/movie/show title - insert(Kwave::INF_ALBUM, ID3FID_ORIGALBUM, - ENC_TEXT); - // Subtitle/Description refinement - insert(Kwave::INF_ANNOTATION, ID3FID_SUBTITLE, - ENC_TEXT); - // User defined text information - insert(Kwave::INF_ANNOTATION, ID3FID_USERTEXT, - ENC_TEXT); - // Kwave::INF_ARCHIVAL - // Original artist(s)/performer(s) - insert(Kwave::INF_AUTHOR, ID3FID_ORIGARTIST, - ENC_TEXT_SLASH); - // Involved people list - insert(Kwave::INF_AUTHOR, ID3FID_INVOLVEDPEOPLE, - ENC_TEXT_LIST); - // Involved people list - insert(Kwave::INF_AUTHOR, ID3FID_INVOLVEDPEOPLE2, - ENC_TEXT_LIST); - // Band/orchestra/accompaniment - insert(Kwave::INF_AUTHOR, ID3FID_BAND, - ENC_TEXT); - // Original lyricist(s)/text writer(s) - insert(Kwave::INF_AUTHOR, ID3FID_ORIGLYRICIST, - ENC_TEXT_SLASH); - // Official artist/performer webpage - insert(Kwave::INF_AUTHOR, ID3FID_WWWARTIST, - ENC_TEXT_URL); - // Official publisher webpage - insert(Kwave::INF_AUTHOR, ID3FID_WWWPUBLISHER, - ENC_TEXT_URL); - // Kwave::INF_BITRATE_LOWER - // Kwave::INF_BITRATE_NOMINAL - // Kwave::INF_BITRATE_UPPER - // Kwave::INF_BITS_PER_SAMPLE - // Part of a set - insert(Kwave::INF_CD, ID3FID_PARTINSET, - ENC_TEXT_PARTINSET); - insert(Kwave::INF_CDS, ID3FID_PARTINSET, - ENC_TEXT_PARTINSET); - // Internet radio station name - insert(Kwave::INF_COMMISSIONED, ID3FID_NETRADIOSTATION, - ENC_TEXT); - // Internet radio station owner - insert(Kwave::INF_COMMISSIONED, ID3FID_NETRADIOOWNER, - ENC_TEXT); - // Comments - insert(Kwave::INF_COMMENTS, ID3FID_COMMENT, - ENC_COMMENT); - // Official audio source webpage - insert(Kwave::INF_CONTACT, ID3FID_WWWAUDIOSOURCE, - ENC_TEXT_SLASH); - // Official internet radio station homepage - insert(Kwave::INF_CONTACT, ID3FID_WWWRADIOPAGE, - ENC_TEXT_SLASH); - // Official audio file webpage - insert(Kwave::INF_CONTACT, ID3FID_WWWAUDIOFILE, - ENC_TEXT_SLASH); - // Ownership (not supported by id3lib) - // (Kwave::INF_CONTACT, ID3FID_OWNERSHIP, - // ENC_OWNERSHIP?); - // Copyright message. - insert(Kwave::INF_COPYRIGHT, ID3FID_COPYRIGHT, - ENC_TEXT); - // Copyright/Legal information - insert(Kwave::INF_COPYRIGHT, ID3FID_WWWCOPYRIGHT, - ENC_TEXT_URL); - // Terms of use - insert(Kwave::INF_COPYRIGHT, ID3FID_TERMSOFUSE, - ENC_TERMS_OF_USE); - // Kwave::INF_COPYRIGHTED - - // Recording dates - insert(Kwave::INF_CREATION_DATE, ID3FID_RECORDINGDATES, - ENC_TEXT_TIMESTAMP); - // Recording time (not supported by id3lib) - // (Kwave::INF_CREATION_DATE, ID3FID_RECORDINGTIME, - // ENC_TEXT_TIMESTAMP); - // Date - insert(Kwave::INF_CREATION_DATE, ID3FID_DATE, - ENC_TEXT_TIMESTAMP); - // Year - insert(Kwave::INF_CREATION_DATE, ID3FID_YEAR, - ENC_TEXT_TIMESTAMP); - // Time - insert(Kwave::INF_CREATION_DATE, ID3FID_TIME, - ENC_TEXT_TIMESTAMP); - // Release time (not supported by id3lib) - // (Kwave::INF_CREATION_DATE, ID3FID_RELEASETIME, - // ENC_TEXT_TIMESTAMP); - // Original release year - insert(Kwave::INF_CREATION_DATE, ID3FID_ORIGYEAR, - ENC_TEXT_TIMESTAMP); - // Original release time (not supported by id3lib) - // (Kwave::INF_CREATION_DATE, ID3FID_ORIGRELEASETIME, - // ENC_TEXT_TIMESTAMP); - // Tagging time (not supported by id3lib) - // (Kwave::INF_CREATION_DATE, ID3FID_TAGGINGTIME, - // ENC_TEXT_TIMESTAMP); - // Encoding time (not supported by id3lib) - // (Kwave::INF_CREATION_DATE, ID3FID_ENCODINGTIME, - // ENC_TEXT_TIMESTAMP); - - // Kwave::INF_ENGINEER - // Kwave::INF_FILENAME - // Kwave::INF_FILESIZE - // Content type (Genre) - insert(Kwave::INF_GENRE, ID3FID_CONTENTTYPE, - ENC_GENRE_TYPE); - // ISRC - // ID3 tags (custom/binary) - insert(Kwave::INF_ID3, ID3FID_NOFRAME, - ENC_BINARY); - insert(Kwave::INF_ISRC, ID3FID_ISRC, - ENC_TEXT); - // Kwave::INF_KEYWORDS - // Kwave::INF_LABELS - // Length - insert(Kwave::INF_LENGTH, ID3FID_SONGLEN, - ENC_LENGTH); - // File owner/licensee - insert(Kwave::INF_LICENSE, ID3FID_FILEOWNER, - ENC_TEXT); - // Medium type - insert(Kwave::INF_MEDIUM, ID3FID_MEDIATYPE, - ENC_TEXT); - // Kwave::INF_MIMETYPE - // Kwave::INF_MPEG_EMPHASIS - // Kwave::INF_MPEG_LAYER - // Kwave::INF_MPEG_MODEEXT - // Kwave::INF_MPEG_VERSION - // Title/songname/content description - insert(Kwave::INF_NAME, ID3FID_TITLE, - ENC_TEXT); - // Composer - insert(Kwave::INF_ORGANIZATION, ID3FID_COMPOSER, - ENC_TEXT_SLASH); - // Publisher - insert(Kwave::INF_ORGANIZATION, ID3FID_PUBLISHER, - ENC_TEXT_SLASH); - // Produced notice - insert(Kwave::INF_ORGANIZATION, ID3FID_PRODUCEDNOTICE, - ENC_TEXT_SLASH); - // Kwave::INF_ORIGINAL - // Lyricist/Text writer - insert(Kwave::INF_PERFORMER, ID3FID_LYRICIST, - ENC_TEXT_SLASH); - // Lead performer(s)/Soloist(s). - insert(Kwave::INF_PERFORMER, ID3FID_LEADARTIST, - ENC_TEXT_SLASH); - // Musician credits list - insert(Kwave::INF_PERFORMER, ID3FID_MUSICIANCREDITLIST, - ENC_TEXT_SLASH); - // Conductor/performer refinement - insert(Kwave::INF_PERFORMER, ID3FID_CONDUCTOR, - ENC_TEXT); - // Private frame - // Kwave::INF_PRIVATE - // Kwave::INF_PRODUCT - // Kwave::INF_SAMPLE_FORMAT - // Kwave::INF_SAMPLE_RATE - insert(Kwave::INF_SOFTWARE, ID3FID_ENCODERSETTINGS, - ENC_TEXT); - // Kwave::INF_SOURCE - // Kwave::INF_SOURCE_FORM - // Kwave::INF_SUBJECT - // Encoded by. - insert(Kwave::INF_TECHNICAN, ID3FID_ENCODEDBY, - ENC_TEXT); - // Track number/Position in set - insert(Kwave::INF_TRACK, ID3FID_TRACKNUM, - ENC_TRACK_NUM); - // Number of Tracks - insert(Kwave::INF_TRACKS, ID3FID_TRACKNUM, - ENC_TRACK_NUM); - // Kwave::INF_VBR_QUALITY - // Interpreted, remixed / modified by - insert(Kwave::INF_VERSION, ID3FID_MIXARTIST, - ENC_TEXT); - // Set subtitle - insert(Kwave::INF_VERSION, ID3FID_SETSUBTITLE, - ENC_TEXT); - // ID3FID_PRIVATE => user defined data - - insert(Kwave::INF_UNKNOWN, ID3FID_NOFRAME, - ENC_NONE); -} - -//*************************************************************************** -void Kwave::ID3_PropertyMap::insert(const Kwave::FileProperty property, - const ID3_FrameID id, const Kwave::ID3_PropertyMap::Encoding encoding) -{ - Kwave::ID3_PropertyMap::Mapping mapping; - - mapping.m_property = property; - mapping.m_frame_id = id; - mapping.m_encoding = encoding; - m_list.append(mapping); -} - -//*************************************************************************** -ID3_FrameID Kwave::ID3_PropertyMap::findProperty( - const Kwave::FileProperty property) const -{ - for(const Kwave::ID3_PropertyMap::Mapping &m : m_list) { - if ((m.m_property == property) && supported(m.m_frame_id)) - return m.m_frame_id; - } - return ID3FID_NOFRAME; -} - -//*************************************************************************** -bool Kwave::ID3_PropertyMap::containsProperty( - const Kwave::FileProperty property) const -{ - for(const Kwave::ID3_PropertyMap::Mapping &m : m_list) { - if ((m.m_property == property) && supported(m.m_frame_id)) - return true; - } - return false; -} - -//*************************************************************************** -bool Kwave::ID3_PropertyMap::containsID(const ID3_FrameID id) const -{ - if (!supported(id)) - return false; - - for(const Kwave::ID3_PropertyMap::Mapping &m : m_list) { - if (m.m_frame_id == id) - return true; - } - return false; -} - -//*************************************************************************** -Kwave::ID3_PropertyMap::Encoding Kwave::ID3_PropertyMap::encoding( - const ID3_FrameID id) const -{ - for (const Kwave::ID3_PropertyMap::Mapping &m : m_list) { - if (m.m_frame_id == id) - return m.m_encoding; - } - return ID3_PropertyMap::ENC_NONE; -} - -//*************************************************************************** -QList<ID3_FrameID> Kwave::ID3_PropertyMap::knownIDs() const -{ - QList<ID3_FrameID> list; - for (const Kwave::ID3_PropertyMap::Mapping &m : m_list) { - if (!list.contains(m.m_frame_id)) - list.append(m.m_frame_id); - } - return list; -} - -//*************************************************************************** -Kwave::FileProperty Kwave::ID3_PropertyMap::property(const ID3_FrameID id) const -{ - for (const Kwave::ID3_PropertyMap::Mapping &m : m_list) { - if (m.m_frame_id == id) return m.m_property; - } - return Kwave::INF_UNKNOWN; -} - -//*************************************************************************** -QList<Kwave::FileProperty> Kwave::ID3_PropertyMap::properties() const -{ - QList<Kwave::FileProperty> list; - for (const Kwave::ID3_PropertyMap::Mapping &m : m_list) { - if (!list.contains(m.m_property)) - list.append(m.m_property); - } - return list; -} - -//*************************************************************************** -bool Kwave::ID3_PropertyMap::supported(const ID3_FrameID id) const -{ - ID3_FrameInfo frameInfo; - return (frameInfo.NumFields(id) != 0); -} - -//*************************************************************************** -//*************************************************************************** diff --git a/plugins/codec_mp3/ID3_PropertyMap.h b/plugins/codec_mp3/ID3_PropertyMap.h deleted file mode 100644 index b67ffc6b..00000000 --- a/plugins/codec_mp3/ID3_PropertyMap.h +++ /dev/null @@ -1,130 +0,0 @@ -/************************************************************************* - ID3_PropertyMap.h - map for translating properties to ID3 frame tags - ------------------- - begin : Sat Jul 30 2012 - copyright : (C) 2012 by Thomas Eschenbacher - email : [email protected] - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#ifndef ID3_PROPERTY_MAP_H -#define ID3_PROPERTY_MAP_H - -#include "config.h" - -#include <QList> - -#include <id3/globals.h> - -#include "libkwave/FileInfo.h" - -namespace Kwave -{ - - class ID3_PropertyMap - { - public: - - /** encoding of the ID3 tag */ - typedef enum { - ENC_NONE = 0, - ENC_COMMENT, /**< comment frame */ - ENC_GENRE_TYPE, /**< genre type, numeric or text */ - ENC_LENGTH, /**< string with length in ms */ - ENC_TERMS_OF_USE, /**< terms of use */ - ENC_TEXT, /**< text, appended by ';' */ - ENC_TEXT_SLASH, /**< text list, separated by slash '/' */ - ENC_TEXT_LIST, /**< list of zero terminated strings */ - ENC_TEXT_URL, /**< URL */ - ENC_TEXT_PARTINSET, /**< part in set (x/y) */ - ENC_TEXT_TIMESTAMP, /**< ISO 8601 timestamp */ - ENC_TRACK_NUM, /**< track/tracks (x/y) */ - ENC_BINARY /**< binary/custom data */ - } Encoding; - - /** Default constructor, with initializing */ - ID3_PropertyMap(); - - /** Destructor */ - virtual ~ID3_PropertyMap() {} - - /** - * Returns the frame ID of a property or an empty string - * if nothing found (reverse lookup). - */ - ID3_FrameID findProperty(const Kwave::FileProperty property) const; - - /** Returns true if the map contains a given property */ - bool containsProperty(const Kwave::FileProperty property) const; - - /** - * insert a new property / frame ID mapping - * - * @param property a Kwave FileProperty - * @param id a ID3 frame ID - * @param encoding the type of the encoding of the tag - */ - void insert(const Kwave::FileProperty property, const ID3_FrameID id, - const Encoding encoding); - - /** - * returns true if a given ID3 frame ID is in the map - * - * @param id a ID3 frame ID - * @return true if found, false if not - */ - bool containsID(const ID3_FrameID id) const; - - /** - * returns the encoding of the ID3 frame - * - * @param id a ID3 frame ID - * @return the encoding of the content of the frame - */ - Encoding encoding(const ID3_FrameID id) const; - - /** returns a list of all known ID3 frame IDs */ - QList<ID3_FrameID> knownIDs() const; - - /** - * Returns the first FileProperty that matches a given ID3 frame ID - * - * @param id a ID3 frame ID - * @return a FileProperty - */ - Kwave::FileProperty property(const ID3_FrameID id) const; - - /** Returns a list with all supported properties */ - QList<Kwave::FileProperty> properties() const; - - private: - - /** returns true if a frame is supported by id3lib */ - bool supported(const ID3_FrameID id) const; - - private: - /** container for one mapping */ - typedef struct - { - Kwave::FileProperty m_property; /**< the Kwave property */ - ID3_FrameID m_frame_id; /**< ID3 frame ID */ - Encoding m_encoding; /**< data encoding */ - } Mapping; - - /** list of mappings */ - QList<Mapping> m_list; - }; -} - -#endif /* ID3_PROPERTY_MAP_H */ - -//*************************************************************************** -//*************************************************************************** diff --git a/plugins/codec_mp3/ID3_QIODeviceReader.cpp b/plugins/codec_mp3/ID3_QIODeviceReader.cpp deleted file mode 100644 index 065863e9..00000000 --- a/plugins/codec_mp3/ID3_QIODeviceReader.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/************************************************************************* - ID3_QIODeviceReader.cpp - Adapter between QIODevice and ID3_Reader - ------------------- - begin : Wed Aug 14 2002 - copyright : (C) 2002 by Thomas Eschenbacher - email : [email protected] - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#include "config.h" - -#include <QIODevice> - -#include "ID3_QIODeviceReader.h" - -//*************************************************************************** -Kwave::ID3_QIODeviceReader::ID3_QIODeviceReader(QIODevice &source) - :ID3_Reader(), m_source(source) -{ -} - -//*************************************************************************** -Kwave::ID3_QIODeviceReader::~ID3_QIODeviceReader() -{ -} - -//*************************************************************************** -void Kwave::ID3_QIODeviceReader::close() -{ -} - -//*************************************************************************** -ID3_Reader::pos_type Kwave::ID3_QIODeviceReader::getBeg() -{ - return 0; -} - -//*************************************************************************** -ID3_Reader::pos_type Kwave::ID3_QIODeviceReader::getEnd() -{ - return static_cast<ID3_Reader::pos_type>(m_source.size()); -} - -//*************************************************************************** -ID3_Reader::pos_type Kwave::ID3_QIODeviceReader::getCur() -{ - return static_cast<ID3_Reader::pos_type>(m_source.pos()); -} - -//*************************************************************************** -ID3_Reader::pos_type Kwave::ID3_QIODeviceReader::setCur( - ID3_Reader::pos_type pos) -{ - if (!m_source.seek(static_cast<qint64>(pos))) - return static_cast<ID3_Reader::pos_type>(-1); - return static_cast<ID3_Reader::pos_type>(m_source.pos()); -} - -//*************************************************************************** -ID3_Reader::int_type Kwave::ID3_QIODeviceReader::readChar() -{ - unsigned char c = 0; - m_source.getChar(reinterpret_cast<char *>(&c)); - return static_cast<ID3_Reader::int_type>(c); -} - -//*************************************************************************** -ID3_Reader::int_type Kwave::ID3_QIODeviceReader::peekChar() -{ - qint64 pos = m_source.pos(); - ID3_Reader::int_type ch = readChar(); - m_source.seek(pos); - return ch; -} - -//*************************************************************************** -ID3_Reader::size_type Kwave::ID3_QIODeviceReader::readChars( - char_type buf[], size_type len) -{ - qint64 size = m_source.read( - reinterpret_cast<char *>(&(buf[0])), - static_cast<qint64>(len) - ); - return static_cast<ID3_Reader::size_type>(size); -} - -//*************************************************************************** -ID3_Reader::size_type Kwave::ID3_QIODeviceReader::readChars( - char buf[], size_type len) -{ - return this->readChars(reinterpret_cast<char_type *>(buf), len); -} - -//*************************************************************************** -//*************************************************************************** diff --git a/plugins/codec_mp3/ID3_QIODeviceReader.h b/plugins/codec_mp3/ID3_QIODeviceReader.h deleted file mode 100644 index de1be79b..00000000 --- a/plugins/codec_mp3/ID3_QIODeviceReader.h +++ /dev/null @@ -1,82 +0,0 @@ -/************************************************************************* - ID3_QIODeviceReader.h - Adapter between QIODevice and ID3_Reader - ------------------- - begin : Wed Aug 14 2002 - copyright : (C) 2002 by Thomas Eschenbacher - email : [email protected] - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#ifndef ID3_QIODEVICE_READER_H -#define ID3_QIODEVICE_READER_H - -#include "config.h" - -#include <id3/globals.h> -#include <id3/reader.h> - -class QIODevice; - -namespace Kwave -{ - /** - * @class ID3_QIODeviceReader - * Adapter between QIODevice and ID3_Reader - */ - class ID3_QIODeviceReader: public ID3_Reader - { - public: - - /** Constructor */ - explicit ID3_QIODeviceReader(QIODevice &source); - - /** Destructor */ - virtual ~ID3_QIODeviceReader(); - - /** Close the source. Not implemented. */ - void close() override; - - /** Get the start position, always zero */ - ID3_Reader::pos_type getBeg() override; - - /** Get the end position, identical to size()-1 */ - ID3_Reader::pos_type getEnd() override; - - /** Returns the current position */ - ID3_Reader::pos_type getCur() override; - - /** Sets a new position and returns the new one */ - virtual ID3_Reader::pos_type setCur(ID3_Reader::pos_type pos = 0) - override; - - /** Reads out one single character */ - ID3_Reader::int_type readChar() override; - - /** Reads one character without advancing the current position */ - ID3_Reader::int_type peekChar() override; - - /** Read out a block of characters */ - virtual size_type readChars(char_type buf[], size_type len) - override; - virtual size_type readChars(char buf[], size_type len) - override; - - private: - - /** reference to a QIODevice that is used as source */ - QIODevice &m_source; - }; -} - -#endif /* ID3_QIODEVICE_READER_H */ - -//*************************************************************************** -//*************************************************************************** diff --git a/plugins/codec_mp3/ID3_QIODeviceWriter.cpp b/plugins/codec_mp3/ID3_QIODeviceWriter.cpp deleted file mode 100644 index 0e315434..00000000 --- a/plugins/codec_mp3/ID3_QIODeviceWriter.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/************************************************************************* - ID3_QIODeviceWriter.cpp - Adapter between QIODevice and ID3_Writer - ------------------- - begin : Mon May 28 2012 - copyright : (C) 2012 by Thomas Eschenbacher - email : [email protected] - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#include "config.h" - -#include <QIODevice> - -#include "ID3_QIODeviceWriter.h" - -//*************************************************************************** -Kwave::ID3_QIODeviceWriter::ID3_QIODeviceWriter(QIODevice &dest) - :ID3_Writer(), m_dest(dest), m_written(0) -{ -} - -//*************************************************************************** -Kwave::ID3_QIODeviceWriter::~ID3_QIODeviceWriter() -{ -} - -//*************************************************************************** -void Kwave::ID3_QIODeviceWriter::close() -{ -} - -//*************************************************************************** -void Kwave::ID3_QIODeviceWriter::flush() -{ -} - -//*************************************************************************** -ID3_Writer::pos_type Kwave::ID3_QIODeviceWriter::getBeg() -{ - return 0; -} - -//*************************************************************************** -ID3_Writer::pos_type Kwave::ID3_QIODeviceWriter::getEnd() -{ - return getMaxSize(); -} - -//*************************************************************************** -ID3_Writer::pos_type Kwave::ID3_QIODeviceWriter::getCur() -{ - return m_written; -} - -//*************************************************************************** -ID3_Writer::size_type Kwave::ID3_QIODeviceWriter::getSize() -{ - return m_written; -} - -//*************************************************************************** -ID3_Writer::size_type Kwave::ID3_QIODeviceWriter::getMaxSize() -{ - return (1U << ((sizeof(ID3_Writer::size_type) * 8) - 1)); -} - -//*************************************************************************** -ID3_Writer::size_type Kwave::ID3_QIODeviceWriter::writeChars( - const ID3_Writer::char_type buf[], ID3_Writer::size_type len) -{ - return this->writeChars(reinterpret_cast<const char *>(buf), len); -} - -//*************************************************************************** -ID3_Writer::size_type Kwave::ID3_QIODeviceWriter::writeChars( - const char buf[], ID3_Writer::size_type len) -{ - ID3_Writer::size_type bytes = static_cast<ID3_Writer::size_type>( - m_dest.write(&(buf[0]), static_cast<qint64>(len))); - if (bytes > 0) - m_written += bytes; - return bytes; -} - -//*************************************************************************** -bool Kwave::ID3_QIODeviceWriter::atEnd() -{ - return false; -} - -//*************************************************************************** -//*************************************************************************** diff --git a/plugins/codec_mp3/ID3_QIODeviceWriter.h b/plugins/codec_mp3/ID3_QIODeviceWriter.h deleted file mode 100644 index 2ab9ce88..00000000 --- a/plugins/codec_mp3/ID3_QIODeviceWriter.h +++ /dev/null @@ -1,93 +0,0 @@ -/************************************************************************* - ID3_QIODeviceWriter.h - Adapter between QIODevice and ID3_Writer - ------------------- - begin : Mon May 28 2012 - copyright : (C) 2012 by Thomas Eschenbacher - email : [email protected] - ***************************************************************************/ - -/*************************************************************************** - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - ***************************************************************************/ - -#ifndef ID3_QIODEVICE_WRITER_H -#define ID3_QIODEVICE_WRITER_H - -#include "config.h" - -#include <id3/globals.h> -#include <id3/writer.h> - -class QIODevice; - -namespace Kwave -{ - /** - * @class ID3_QIODeviceWriter - * Adapter between QIODevice and ID3_Writer - */ - class ID3_QIODeviceWriter: public ID3_Writer - { - public: - - /** Constructor */ - explicit ID3_QIODeviceWriter(QIODevice &dest); - - /** Destructor */ - virtual ~ID3_QIODeviceWriter(); - - /** Close the destination. Not implemented. */ - void close() override; - - /** Flush the destination, not implemented (not needed) */ - void flush() override; - - /** Get the start position, always zero */ - ID3_Writer::pos_type getBeg() override; - - /** Get the end position, identical to size()-1 */ - ID3_Writer::pos_type getEnd() override; - - /** Returns the current position */ - ID3_Writer::pos_type getCur() override; - - /** Returns the number of bytes written */ - ID3_Writer::size_type getSize() override; - - /** Returns the maximum number of bytes written */ - ID3_Writer::size_type getMaxSize() override; - - /** - * Write up to len characters into buf and advance the internal position - * accordingly. - */ - virtual ID3_Writer::size_type writeChars( - const ID3_Writer::char_type buf[], ID3_Writer::size_type len) - override; - - virtual ID3_Writer::size_type writeChars( - const char buf[], ID3_Writer::size_type len) - override; - - /** returns true if the writer has read eof (always false) */ - bool atEnd() override; - - private: - - /** reference to a QIODevice that is used as destination */ - QIODevice &m_dest; - - /** number of bytes written */ - ID3_Writer::size_type m_written; - }; -} - -#endif /* ID3_QIODEVICE_WRITER_H */ - -//*************************************************************************** -//*************************************************************************** diff --git a/plugins/codec_mp3/MP3Encoder.cpp b/plugins/codec_mp3/MP3Encoder.cpp index c4bab547..ec5d61cb 100644 --- a/plugins/codec_mp3/MP3Encoder.cpp +++ b/plugins/codec_mp3/MP3Encoder.cpp @@ -20,9 +20,9 @@ #include <math.h> #include <new> -#include <id3/globals.h> -#include <id3/misc_support.h> -#include <id3/tag.h> +#include <taglib/commentsframe.h> +#include <taglib/textidentificationframe.h> +#include <taglib/unknownframe.h> #include <QBuffer> #include <QByteArray> @@ -45,11 +45,10 @@ #include "libkwave/String.h" #include "libkwave/Utils.h" -#include "ID3_QIODeviceReader.h" -#include "ID3_QIODeviceWriter.h" #include "MP3CodecPlugin.h" #include "MP3Encoder.h" #include "MP3EncoderSettings.h" +#include "TagLib_PropertyMap.h" /***************************************************************************/ Kwave::MP3Encoder::MP3Encoder() @@ -96,223 +95,270 @@ QList<Kwave::FileProperty> Kwave::MP3Encoder::supportedProperties() /***************************************************************************/ void Kwave::MP3Encoder::encodeID3Tags(const Kwave::MetaDataList &meta_data, - ID3_Tag &tag) + TagLib::ID3v2::Tag &tag) { + // encode meta data with taglib const Kwave::FileInfo info(meta_data); + const QMap<Kwave::FileProperty, QVariant> props = info.properties(); - const QMap<Kwave::FileProperty, QVariant> properties(info.properties()); - QMap<Kwave::FileProperty, QVariant>::const_iterator it; - for (it = properties.begin(); it != properties.end(); ++it) { - const Kwave::FileProperty &property = it.key(); - const QVariant &value = it.value(); - - ID3_FrameID id = m_property_map.findProperty(property); - if ((property != Kwave::FileProperty::INF_ID3) && - (id == ID3FID_NOFRAME)) continue; - - if (info.contains(Kwave::INF_CD) && (property == Kwave::INF_CDS)) - continue; /* INF_CDS has already been handled by INF_CD */ - if (info.contains(Kwave::INF_TRACK) && (property == Kwave::INF_TRACKS)) - continue; /* INF_TRACKS has already been handled by INF_TRACK */ - - ID3_Frame *frame = new(std::nothrow) ID3_Frame; - Q_ASSERT(frame); - if (!frame) break; - - QString str_val = value.toString(); -// qDebug("encoding ID3 tag #%02d, property='%s', value='%s'", -// static_cast<int>(id), -// DBG(info.name(property)), -// DBG(str_val) -// ); - - // encode in UCS16 - frame->SetID(id); - ID3_Field *field = frame->GetField(ID3FN_TEXT); - if ((property != Kwave::FileProperty::INF_ID3) && !field) { - qWarning("no field, frame id=%d", static_cast<int>(id)); - delete frame; + for (auto it = props.constBegin(); it != props.constEnd(); ++it) + { + const Kwave::FileProperty prop = it.key(); + + // skip separate total track count if already merged into TRCK + if ((prop == Kwave::INF_TRACKS) && info.contains(Kwave::INF_TRACK)) + continue; + + // skip separate total cd count if already merged into TPOS + if ((prop == Kwave::INF_CDS) && info.contains(Kwave::INF_CD)) + continue; + + const TagLib::ByteVector frame_id = m_property_map.findProperty(prop); + if (frame_id.isEmpty()) continue; - } - bool ok = true; - ID3_PropertyMap::Encoding encoding = m_property_map.encoding(id); - switch (encoding) { - case ID3_PropertyMap::ENC_TEXT_PARTINSET: + const TagLib_PropertyMap::Encoding enc = + m_property_map.encoding(frame_id); + switch (enc) + { + case TagLib_PropertyMap::ENC_COMMENT: { - field->SetEncoding(ID3TE_UTF16); + // create comment frame with language code + const QStringList list = it.value().toStringList(); + for (QString c : list) + { + if (c.isEmpty()) + continue; - // if "number of CDs" is available: append with "/" - int cds = info.get(Kwave::INF_CDS).toInt(); - if (cds > 0) - str_val += _("/%1").arg(cds); + TagLib::ByteVector lang("eng", 3); + if ((c.length() > 5) && + (c.at(0) == QLatin1Char('[')) && + (c.at(4) == QLatin1Char(']'))) + { + const QString l = c.mid(1, 3); + lang = TagLib::ByteVector(l.toLatin1().constData(), 3); + c = c.mid(5).trimmed(); + } - field->Set(static_cast<const unicode_t *>(str_val.utf16())); + TagLib::ID3v2::CommentsFrame *frame = + new(std::nothrow) TagLib::ID3v2::CommentsFrame( + TagLib::String::UTF8); + if (!frame) + continue; + + frame->setLanguage(lang); + frame->setText( + TagLib::String(c.toUtf8().constData(), + TagLib::String::UTF8)); + tag.addFrame(frame); + } break; } - case ID3_PropertyMap::ENC_TRACK_NUM: + case TagLib_PropertyMap::ENC_TRACK_NUM: { - // if "number of tracks" is available: append with "/" - int tracks = info.get(Kwave::INF_TRACKS).toInt(); - if (tracks > 0) - str_val += _("/%1").arg(tracks); + // format track number as "track/total" if total tracks count + QString val = it.value().toString(); + if (val.isEmpty()) + break; - field->SetEncoding(ID3TE_UTF16); - field->Set(static_cast<const unicode_t *>(str_val.utf16())); + if ((prop == Kwave::INF_TRACK) && info.contains(Kwave::INF_TRACKS)) + { + const QString total = info.get(Kwave::INF_TRACKS).toString(); + if (!total.isEmpty()) + val += QLatin1Char('/') + total; + } + + TagLib::ID3v2::TextIdentificationFrame *frame = + new(std::nothrow) TagLib::ID3v2::TextIdentificationFrame( + frame_id, TagLib::String::UTF8); + if (!frame) + break; + + frame->setText( + TagLib::String(val.toUtf8().constData(), + TagLib::String::UTF8)); + tag.addFrame(frame); break; } - case ID3_PropertyMap::ENC_TERMS_OF_USE: - // the same as ENC_COMMENT, but without "Description" - /* FALLTHROUGH */ - case ID3_PropertyMap::ENC_COMMENT: + case TagLib_PropertyMap::ENC_TEXT_PARTINSET: { - ok = false; - QStringList list = info.get(property).toStringList(); - for (QString c : list) - { - delete frame; - frame = new(std::nothrow) ID3_Frame; - Q_ASSERT(frame != nullptr); - if (frame == nullptr) continue; - frame->SetID(id); - - // detect language at the start "[xxx] " - if ( (c.length() > 5) && - (c.at(0) == QLatin1Char('[')) && - (c.at(4) == QLatin1Char(']')) ) { - QString lang = c.mid(1,3); - c = c.mid(5).trimmed(); - frame->GetField(ID3FN_LANGUAGE)->Set( - static_cast<const char *>(lang.toLatin1().data())); - } - /* frame->GetField(ID3FN_DESCRIPTION)->Set("..."); */ - field = frame->GetField(ID3FN_TEXT); - if (field) { - field->SetEncoding(ID3TE_UTF16); - field->Set(static_cast<const unicode_t *>(c.utf16())); - } + // format disc number as "disc/total" if total discs count + QString val = it.value().toString(); + if (val.isEmpty()) + break; - if (tag.AttachFrame(frame)) { - frame = nullptr; - ok = true; - } + if ((prop == Kwave::INF_CD) && info.contains(Kwave::INF_CDS)) + { + const QString total = info.get(Kwave::INF_CDS).toString(); + if (!total.isEmpty()) + val += QLatin1Char('/') + total; } + + TagLib::ID3v2::TextIdentificationFrame *frame = + new(std::nothrow) TagLib::ID3v2::TextIdentificationFrame( + frame_id, TagLib::String::UTF8); + if (!frame) + break; + + frame->setText( + TagLib::String(val.toUtf8().constData(), + TagLib::String::UTF8)); + tag.addFrame(frame); break; } - case ID3_PropertyMap::ENC_GENRE_TYPE: + case TagLib_PropertyMap::ENC_GENRE_TYPE: { - int genre = Kwave::GenreType::fromID3(str_val); - if (genre >= 0) - str_val = Kwave::GenreType::name(genre, false); - // else: user defined genre type, take it as it is + // format genre name from numerical id if known + QString val = it.value().toString(); + if (val.isEmpty()) + break; - field->SetEncoding(ID3TE_UTF16); - field->Set(static_cast<const unicode_t *>(str_val.utf16())); + const int genre = Kwave::GenreType::fromID3(val); + if (genre >= 0) + val = Kwave::GenreType::name(genre, false); + + TagLib::ID3v2::TextIdentificationFrame *frame = + new(std::nothrow) TagLib::ID3v2::TextIdentificationFrame( + frame_id, TagLib::String::UTF8); + if (!frame) + break; + + frame->setText( + TagLib::String(val.toUtf8().constData(), + TagLib::String::UTF8)); + tag.addFrame(frame); break; } - case ID3_PropertyMap::ENC_LENGTH: + case TagLib_PropertyMap::ENC_TEXT_TIMESTAMP: { - // length in milliseconds - const double rate = info.rate(); - const sample_index_t samples = info.length(); - if ((rate > 0) && samples) { - const sample_index_t ms = static_cast<sample_index_t>( - (static_cast<double>(samples) * 1E3) / rate); - - str_val = QString::number(ms); - - field->SetEncoding(ID3TE_UTF16); - field->Set(static_cast<const unicode_t *>(str_val.utf16())); - } else - ok = false; + // format timestamp or year + const QString val = it.value().toString(); + if (val.isEmpty()) + break; + + QString s = Kwave::string2date(val); + if (s.isEmpty()) + { + const int year = val.toInt(); + if ((year > 0) && (year < 9999)) + s = _("%1").arg(year, 4, 10, QLatin1Char('0')); + } + if (s.isEmpty()) + break; + + TagLib::ID3v2::TextIdentificationFrame *frame = + new(std::nothrow) TagLib::ID3v2::TextIdentificationFrame( + frame_id, TagLib::String::UTF8); + if (!frame) + break; + + frame->setText( + TagLib::String(s.toUtf8().constData(), + TagLib::String::UTF8)); + tag.addFrame(frame); break; } - case ID3_PropertyMap::ENC_TEXT_TIMESTAMP: + case TagLib_PropertyMap::ENC_TEXT_LIST: /* FALLTHROUGH */ + case TagLib_PropertyMap::ENC_TEXT_SLASH: { - // ISO 8601 timestamp: "yyyy-MM-ddTHH:mm:ss" - QString s = Kwave::string2date(str_val); - - // if failed, try "yyyy" format (year only) - if (!s.length()) { - int year = str_val.toInt(); - if ((year > 0) && (year < 9999)) { - frame->SetID(ID3FID_YEAR); - // -> re-get the field ! - // it has become invalid through "SetID()" - field = frame->GetField(ID3FN_TEXT); - if (!field) { - qWarning("no field, frame id=%d", - static_cast<int>(id)); - ok = false; - break; - } - s = _("%1").arg(year, 4, 10, QLatin1Char('0')); - } + // create text identification frame with list of strings + const QStringList list = it.value().toStringList(); + if (list.isEmpty()) + break; + + TagLib::ID3v2::TextIdentificationFrame *frame = + new(std::nothrow) TagLib::ID3v2::TextIdentificationFrame( + frame_id, TagLib::String::UTF8); + if (!frame) + break; + + TagLib::StringList taglib_list; + for (const QString &item : list) + { + if (!item.isEmpty()) + taglib_list.append( + TagLib::String(item.toUtf8().constData(), + TagLib::String::UTF8)); } - - if (s.length()) { - field->SetEncoding(ID3TE_UTF16); - field->Set(static_cast<const unicode_t *>(s.utf16())); - } else { - // date is invalid, unknown format - qWarning("MP3Encoder::encodeID3Tags(): invalid date: '%s'", - DBG(str_val)); - ok = false; + if (taglib_list.isEmpty()) + { + delete frame; + break; } + + frame->setText(taglib_list); + tag.addFrame(frame); break; } - case ID3_PropertyMap::ENC_TEXT_SLASH: /* FALLTHROUGH */ - case ID3_PropertyMap::ENC_TEXT_URL: /* FALLTHROUGH */ - case ID3_PropertyMap::ENC_TEXT: - field->SetEncoding(ID3TE_UTF16); - field->Set(static_cast<const unicode_t *>(str_val.utf16())); + case TagLib_PropertyMap::ENC_TEXT: /* FALLTHROUGH */ + case TagLib_PropertyMap::ENC_TEXT_URL: + { + // create text identification frame + const QString val = it.value().toString(); + if (val.isEmpty()) + break; + + TagLib::ID3v2::TextIdentificationFrame *frame = + new(std::nothrow) TagLib::ID3v2::TextIdentificationFrame( + frame_id, TagLib::String::UTF8); + if (!frame) + break; + + frame->setText( + TagLib::String(val.toUtf8().constData(), + TagLib::String::UTF8)); + tag.addFrame(frame); break; - case ID3_PropertyMap::ENC_BINARY: + } + case TagLib_PropertyMap::ENC_BINARY: { - QStringList frames = value.toStringList(); - for (const QString &f : frames) { - delete frame; - frame = new(std::nothrow) ID3_Frame; - Q_ASSERT(frame != nullptr); - if (frame == nullptr) continue; - - QByteArray raw = QByteArray::fromBase64(f.toLocal8Bit()); - QBuffer buffer(&raw); - buffer.open(QIODevice::ReadOnly); - Kwave::ID3_QIODeviceReader reader(buffer); - if (!frame->Parse(reader)) { - qWarning("MP3Encoder::encodeID3Tags(): " - "parsing ENC_BINARY failed"); - ok = false; + // add raw binary data frame(s) from base64 string list + const QStringList frames = it.value().toStringList(); + for (const QString &f : frames) + { + const QByteArray data = QByteArray::fromBase64(f.toLatin1()); + if (data.isEmpty()) continue; - } - qDebug("attaching custom ID3 frame '%s'", - frame->GetDescription()); - if (tag.AttachFrame(frame)) { - frame = nullptr; - ok = true; - } else { - qWarning("MP3Encoder::encodeID3Tags(): " - "attaching ENC_BINARY frame failed"); - ok = false; + + TagLib::ID3v2::UnknownFrame *frame = + new(std::nothrow) TagLib::ID3v2::UnknownFrame(frame_id); + if (!frame) continue; - } + + const unsigned int len = + static_cast<unsigned int>(data.size()); + frame->setData(TagLib::ByteVector(data.constData(), len)); + tag.addFrame(frame); } break; } - case ID3_PropertyMap::ENC_NONE: /* FALLTHROUGH */ + case TagLib_PropertyMap::ENC_TERMS_OF_USE: + { + // add terms of use text frame + const QString val = it.value().toString(); + if (val.isEmpty()) + break; + + TagLib::ID3v2::UnknownFrame *frame = + new(std::nothrow) TagLib::ID3v2::UnknownFrame(frame_id); + if (!frame) + break; + + const QByteArray utf8 = val.toUtf8(); + const unsigned int len = + static_cast<unsigned int>(utf8.size()); + TagLib::ByteVector payload; + payload.append('\x03'); + payload.append(TagLib::ByteVector("eng", 3)); + payload.append(TagLib::ByteVector(utf8.constData(), len)); + frame->setData(payload); + tag.addFrame(frame); + break; + } default: - ok = false; - break; // ignore + break; } - - if (frame && ok) tag.AttachFrame(frame); - if (!ok) delete frame; - frame = nullptr; } - - tag.Strip(); - tag.Update(); } #define OPTION(__field__) \ @@ -329,14 +375,11 @@ bool Kwave::MP3Encoder::encode(QWidget *widget, Kwave::MultiTrackReader &src, const Kwave::MetaDataList &meta_data) { bool result = true; - ID3_Tag id3_tag; + TagLib::ID3v2::Tag id3_tag; Kwave::MP3EncoderSettings settings; settings.load(); - ID3_TagType id3_tag_type = ID3TT_ID3V2; - id3_tag.SetSpec(ID3V2_LATEST); - const Kwave::FileInfo info(meta_data); // get info: tracks, sample rate @@ -371,9 +414,11 @@ bool Kwave::MP3Encoder::encode(QWidget *widget, Kwave::MultiTrackReader &src, m_dst = &dst; m_params.clear(); - // encode meta data into with id3lib - ID3_QIODeviceWriter id3_writer(dst); + // encode meta data with taglib and write id3v2 header to stream encodeID3Tags(meta_data, id3_tag); + const TagLib::ByteVector tag_data = id3_tag.render(); + if (!tag_data.isEmpty()) + dst.write(tag_data.data(), tag_data.size()); OPTION(m_flags.m_prepend); // optional parameters at the very start @@ -488,10 +533,6 @@ bool Kwave::MP3Encoder::encode(QWidget *widget, Kwave::MultiTrackReader &src, result = false; } - // if a ID3v2 tag is requested, the tag comes at the start - if (id3_tag_type == ID3TT_ID3V2) - id3_tag.Render(id3_writer, id3_tag_type); - // MP3 supports only mono and stereo, prepare a mixer matrix // (not used in case of tracks <= 2) Kwave::MixerMatrix mixer(tracks, out_tracks); @@ -616,10 +657,6 @@ bool Kwave::MP3Encoder::encode(QWidget *widget, Kwave::MultiTrackReader &src, )); } - // if a ID3v1 tag is requested, the tag comes at the end - if (id3_tag_type != ID3TT_ID3V2) - id3_tag.Render(id3_writer, id3_tag_type); - { QMutexLocker _lock(&m_lock); m_dst = nullptr; diff --git a/plugins/codec_mp3/MP3Encoder.h b/plugins/codec_mp3/MP3Encoder.h index 13a3d241..baf925ad 100644 --- a/plugins/codec_mp3/MP3Encoder.h +++ b/plugins/codec_mp3/MP3Encoder.h @@ -22,15 +22,17 @@ #include <climits> +#include <taglib/id3v2tag.h> +#include <taglib/tag.h> + #include <QList> #include <QMutex> #include <QProcess> #include "libkwave/Encoder.h" -#include "ID3_PropertyMap.h" +#include "TagLib_PropertyMap.h" -class ID3_Tag; class QIODevice; class QWidget; @@ -88,12 +90,12 @@ namespace Kwave * @param tag the ID3 tag to receive the ID3 frames */ void encodeID3Tags(const Kwave::MetaDataList &meta_data, - ID3_Tag &tag); + TagLib::ID3v2::Tag &tag); private: /** property - to - ID3 mapping */ - ID3_PropertyMap m_property_map; + TagLib_PropertyMap m_property_map; /** lock for protecting m_dst and m_process */ QMutex m_lock;
