diff --git a/NEWS b/CHANGELOG.md similarity index 73% rename from NEWS rename to CHANGELOG.md index b1c25da0e..c9dac2f54 100644 --- a/NEWS +++ b/CHANGELOG.md @@ -3,6 +3,117 @@ TagLib 2.0 (Jan 24, 2024) * New major version, binary incompatible, but source-compatible with the latest 1.x release if no deprecated features are used. + * Requires a C++17 compiler and uses features of C++17. + * Major code cleanup, fixed warnings issued by compilers and static analyzers. + * Made methods virtual which should have been virtual but could not be + changed to keep binary compatibility, remove related workarounds. + * Removed deprecated functions: + - APE::Item::Item(const String &, const String &) + - APE::Item::toStringList(): Use values() + - APE::Item::value(): Use binaryData() + - ASF::Properties::setLength() + - ByteVector::checksum() + - ByteVector::isNull(): Use isEmpty() + - ByteVector::null + - FLAC::File::setID3v2FrameFactory() + - FLAC::File::streamInfoData() + - FLAC::File::streamLength() + - FLAC::Properties::Properties(File *, ReadStyle) + - FLAC::Properties::sampleWidth(): Use bitsPerSample() + - File::isReadable(): Use system functions + - File::isWritable(): Use system functions + - FileName::str() + - FileRef::create(): Use constructor + - MP4::Tag::itemListMap(): Use itemMap() + - MPC::File::remove(): Use strip() + - MPC::Properties::Properties(const ByteVector &, long, ReadStyle) + - MPEG::File::save(int, ...): Use overload + - MPEG::File::setID3v2FrameFactory(): Use constructor + - MPEG::ID3v2::Frame::Header::Header(const ByteVector &, bool) + - MPEG::ID3v2::Frame::Header::frameAlterPreservation(): Use + fileAlterPreservation() + - MPEG::ID3v2::Frame::Header::setData(const ByteVector &, bool) + - MPEG::ID3v2::Frame::Header::size(unsigned int): Use size() + - MPEG::ID3v2::Frame::Header::unsycronisation(): use unsynchronisation() + - MPEG::ID3v2::Frame::checkEncoding(const StringList &, String::Type): Use + checkTextEncoding(const StringList &, String::Type) + - MPEG::ID3v2::Frame::headerSize(): Use Header::size() + - MPEG::ID3v2::Frame::headerSize(unsigned int): Use + Header::size(unsigned int) + - MPEG::ID3v2::FrameFactory::createFrame(const ByteVector &, bool) + - MPEG::ID3v2::FrameFactory::createFrame(const ByteVector &, unsigned int): + Use createFrame(const ByteVector &, const Header *) + - MPEG::ID3v2::RelativeVolumeFrame::channelType() + - MPEG::ID3v2::RelativeVolumeFrame::peakVolume(): Use peakVolume(ChannelType) + - MPEG::ID3v2::RelativeVolumeFrame::setChannelType() + - MPEG::ID3v2::RelativeVolumeFrame::setPeakVolume(const PeakVolume &): Use + setPeakVolume(const PeakVolume &, ChannelType) + - MPEG::ID3v2::RelativeVolumeFrame::setVolumeAdjustment(float): Use + setVolumeAdjustment(float, ChannelType) + - MPEG::ID3v2::RelativeVolumeFrame::setVolumeAdjustmentIndex(short): Use + setVolumeAdjustmentIndex(short, ChannelType) + - MPEG::ID3v2::RelativeVolumeFrame::volumeAdjustment(): Use + volumeAdjustment(ChannelType) + - MPEG::ID3v2::RelativeVolumeFrame::volumeAdjustmentIndex(): Use + volumeAdjustmentIndex(ChannelType) + - MPEG::ID3v2::Tag::footer() + - MPEG::ID3v2::Tag::render(int): Use render(Version) + - MPEG::XingHeader::xingHeaderOffset() + - Ogg::Page::getCopyWithNewPageSequenceNumber() + - Ogg::XiphComment::removeField(): Use removeFields() + - PropertyMap::unsupportedData(): Returns now const reference, use + addUnsupportedData() to add keys + - RIFF::AIFF::Properties::Properties(const ByteVector &, ReadStyle) + - RIFF::AIFF::Properties::Properties(const ByteVector &, int, ReadStyle) + - RIFF::AIFF::Properties::sampleWidth(): Use bitsPerSample() + - RIFF::WAV::File::save(TagTypes, bool, int): Use + save(TagTypes, StripTags, Version) + - RIFF::WAV::File::tag(): Returns now a TagUnion, use ID3v2Tag() to get an + ID3v2::Tag + - String::isNull(): Use isEmpty() + - String::null + - TrueAudio::File::setID3v2FrameFactory(): Use constructor + - WavPack::Properties::Properties(const ByteVector &, long, ReadStyle) +* Behavioral changes: + - The basic tag methods (e.g. genre()) separate multiple values with " / " + instead of " ". + - The stream operator for String uses UTF-8 instead of ISO-8859-1 encoding. + - MP4 property ORIGINALDATE is mapped to "----:com.apple.iTunes:ORIGINALDATE" + instead of "----:com.apple.iTunes:originaldate". + * Unified interface for complex properties like pictures. + * Simplified the unified properties interface by providing its methods on + FileRef. + * C bindings: Support for properties (taglib_property_...) and complex + properties like cover art (taglib_complex_property_...), memory I/O streams. + * Support for Direct Stream Digital (DSD) stream files (DSF) and interchange + file format (DSDIFF, DFF), ADTS (AAC) files. + * The runtime version can be queried. + * Additional utility functions ByteVector::fromUShort(), + ByteVector::fromULongLong(), ByteVector::toULongLong(), + ByteVector::toULongLong(), List::sort(). + * Fixed List::setAutoDelete() affecting implicitly shared copies. + * Build system: Direct support for CMake, find_package(TagLib) exports target + TagLib::tag. + * Build system: Fixed PackageConfig to support both relative and absolute paths. + * Build system: utf8cpp is no longer included, it can be provided via a system + package or a Git submodule. + * ASF: Support additional properties ARTISTWEBPAGE, ENCODING, INITIALKEY, + ORIGINALALBUM, ORIGINALARTIST, ORIGINALFILENAME, ORIGINALLYRICIST. + * ID3v2: Fixed extensibility of FrameFactory, use it also for WAV and AIFF + files. + * MP4: Support additional properties OWNER, RELEASEDATE. + * MP4: Introduced ItemFactory allowing clients to support new atom types. + * MP4: Detect duration from mvhd atom if not present in mdhd atom. + * MP4: Fixed type of hdvd atom to be integer instead of boolean. + * MP4: Tolerate trailing garbage in M4A files. + * MPC: Fixed content check in presence of an ID3v2 tag. + * MPEG: Do not scan full file for ID3v2 tag when ReadStyle Fast is used. + * RIFF: Support properties ALBUM, ARRANGER, ARTIST, ARTISTWEBPAGE, BPM, + COMMENT, COMPOSER, COPYRIGHT, DATE, DISCSUBTITLE, ENCODEDBY, ENCODING, + ENCODINGTIME, GENRE, ISRC, LABEL, LANGUAGE, LYRICIST, MEDIA, PERFORMER, + RELEASECOUNTRY, REMIXER, TITLE, TRACKNUMBER. + * WAV: Fixed crash with files having the "id3 " chunk as the only valid chunk. + * Windows: Fixed support for files larger than 2GB. TagLib 1.13.1 (Jul 1, 2023) =========================== diff --git a/Doxyfile.cmake b/Doxyfile.cmake index ce2147844..3c955f2a7 100644 --- a/Doxyfile.cmake +++ b/Doxyfile.cmake @@ -122,7 +122,8 @@ INPUT = @CMAKE_SOURCE_DIR@/taglib INPUT_ENCODING = UTF-8 FILE_PATTERNS = *.h \ *.hh \ - *.H + *.H \ + *.dox RECURSIVE = YES EXCLUDE = EXCLUDE_SYMLINKS = NO diff --git a/INSTALL.md b/INSTALL.md index 48c9f6fb9..1d9862f97 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -1,5 +1,4 @@ -TagLib Installation -=================== +# TagLib Installation TagLib uses the CMake build system. As a user, you will most likely want to build TagLib in release mode and install it into a system-wide location. @@ -19,16 +18,182 @@ If you want to build TagLib without ZLib, you can use make sudo make install -See http://www.cmake.org/cmake/help/runningcmake.html for generic help on -running CMake. - -Mac OS X --------- - -On Mac OS X, you might want to build a framework that can be easily integrated +See [cmake(1)](https://cmake.org/cmake/help/latest/manual/cmake.1.html) for +generic help on running CMake. + +## Build Options + +These are the most important build options. For details, have a look into the +CMakeLists.txt file. + +| Option | Description | +| ----------------------- | ------------------------------------------ | +| `BUILD_SHARED_LIBS` | Build shared libraries | +| `CMAKE_BUILD_TYPE` | Debug, Release, RelWithDebInfo, MinSizeRel | +| `BUILD_EXAMPLES` | Build examples | +| `BUILD_BINDINGS` | Build C bindings | +| `BUILD_TESTING` | Build unit tests | +| `TRACE_IN_RELEASE` | Enable debug output in release builds | +| `WITH_ZLIB` | Whether to build with ZLib (default ON) | +| `ZLIB_ROOT` | Where to find ZLib's root directory | +| `ZLIB_INCLUDE_DIR` | Where to find ZLib's include directory | +| `ZLIB_LIBRARY` | Where to find ZLib's library | +| `CMAKE_INSTALL_PREFIX` | Where to install Taglib | +| `ENABLE_STATIC_RUNTIME` | Link with MSVC runtime statically | +| `BUILD_FRAMEWORK` | Build a macOS framework | + +## Dependencies + +A required dependency is [utf8cpp](https://github.com/nemtrif/utfcpp). You can +install the corresponding package (libutfcpp-dev on Ubuntu, utf8cpp in Homebrew, +utfcpp in vcpkg) or fetch the Git submodule with `git submodule update --init`. + +Optional dependencies are +- [zlib](https://www.zlib.net/): You can disable it with `-DWITH_ZLIB=OFF`, + build and install it from the sources or use a package (zlib1g-dev on Ubuntu, + zlib in vcpkg). It is needed for compressed ID3v2 frames. +- [CppUnit](https://wiki.documentfoundation.org/Cppunit): Is required for unit + tests, which are disabled by default. If you enable them with + `-DBUILD_TESTING=ON`, you can build and install it from the sources or use a + package (libcppunit-dev on Ubuntu, cppunit in Homebrew, cppunit in vcpkg). + If the unit tests are enabled, you can run them with your build tool + (`make check`, `ninja check`) or via CMake + `cmake --build /path/to/build-dir --target check`. + +## UNIX (Including Linux, BSD and macOS) + +#### Building TagLib + +On Linux, you can install the dependencies using the package manager of your +distribution. On macOS with Homebrew, you can use `brew install cppunit utf8cpp` +to install the dependencies. + +``` +# Adapt these environment variables to your directories +TAGLIB_SRC_DIR=$HOME/projects/taglib/src/taglib +TAGLIB_DST_DIR=$HOME/projects/taglib/src/build +cd $TAGLIB_SRC_DIR +cmake -B $TAGLIB_DST_DIR -DBUILD_SHARED_LIBS=ON -DVISIBILITY_HIDDEN=ON \ + -DBUILD_TESTING=ON -DBUILD_EXAMPLES=ON -DBUILD_BINDINGS=ON \ + -DCMAKE_BUILD_TYPE=Release +cmake --build $TAGLIB_DST_DIR --config Release +cmake --build $TAGLIB_DST_DIR --config Release --target check + +# Install to ~/pkg folder +cmake --install $TAGLIB_DST_DIR --config Release --prefix $HOME/pkg --strip + +# Run example from installed package +LD_LIBRARY_PATH=$HOME/pkg/lib $HOME/pkg/bin/tagreader /path/to/audio-file +``` + +#### Building a Project Using TagLib + +As an example for an external application using TagLib, we create a folder +taglib-client and copy the file tagreader.cpp from the examples folder +of the TagLib sources into it. We then add this simple CMakeLists.txt. + +``` +cmake_minimum_required(VERSION 3.5.0) +project(taglib-client) +set(CMAKE_CXX_STANDARD 17) +find_package(ZLIB) +find_package(TagLib 2.0.0 REQUIRED) +add_executable(tagreader tagreader.cpp) +target_link_libraries(tagreader TagLib::tag) +``` + +To build into a folder `build` inside this directory, just run + +``` +# Set this to the path where TagLib is installed +TAGLIB_PREFIX=$HOME/pkg +cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=$TAGLIB_PREFIX +cmake --build build --config Release + +build/tagreader /path/to/audio-file +``` + +If TagLib is installed in a standard location (e.g. /usr, /usr/local), its CMake +configuration is found without setting CMAKE_INSTALL_PREFIX (or alternatives +like CMAKE_PREFIX_PATH, CMAKE_SYSTEM_PREFIX_PATH). + +To use the C-bindings with tagreader_c.c, you can change the last two lines in +CMakeLists.txt to + +``` +add_executable(tagreader_c tagreader_c.c) +target_link_libraries(tagreader_c TagLib::tag_c) +``` + +#### Building a Project Using pkg-config + +Before version 2.0, TagLib did not export CMake configuration, therefore +`pkg-config` could be used. This is still possible. + +Note, however, that `pkg-config` makes it more difficult to use packages which +are not installed in a standard location. You can point `pkg-config` to search +in non-standard locations for .pc-files, but they still contain the install +locations defined when building TagLib. Since we did not give a +`CMAKE_INSTALL_PREFIX` in the example above, the default `/usr/local/` is used. + +``` +PKG_CONFIG_PATH=$HOME/pkg/lib/pkgconfig pkg-config --libs --cflags taglib +-I/usr/local/include -I/usr/local/include/taglib -L/usr/local/lib -ltag -lz +``` + +The following examples use the same build example with additional CMake +parameters affecting the installation location. + +- Using the default prefix `-DCMAKE_INSTALL_PREFIX=/usr/local`: + ``` + -I/usr/local/include -I/usr/local/include/taglib -L/usr/local/lib -ltag -lz + ``` +- Using an absolute prefix `-DCMAKE_INSTALL_PREFIX=/usr`: + ``` + -I/usr/include/taglib -ltag -lz + ``` +- Using absolute lib and include directories + `-DCMAKE_INSTALL_LIBDIR=/abs-lib -DCMAKE_INSTALL_INCLUDEDIR=/abs-include -DCMAKE_INSTALL_PREFIX=/usr`: + ``` + -I/abs-include -I/abs-include/taglib -L/abs-lib -ltag -lz + ``` +- Using relative lib and include directories + `-DCMAKE_INSTALL_LIBDIR=rel-lib -DCMAKE_INSTALL_INCLUDEDIR=rel-include -DCMAKE_INSTALL_PREFIX=/usr`: + ``` + -I/usr/rel-include -I/usr/rel-include/taglib -L/usr/rel-lib -ltag -lz + ``` + This is the output of + ``` + PKG_CONFIG_PATH=$HOME/pkg/rel-lib/pkgconfig pkg-config --libs --cflags taglib + ``` + You could add `--define-prefix` to the `pkg-config` arguments to have the + effective location `$HOME/pkg/` instead of `/usr/` in the output. + +Therefore, the correct paths for our example package would be given when using +the `--define-prefix` feature. + +``` +PKG_CONFIG_PATH=$HOME/pkg/lib/pkgconfig pkg-config --define-prefix --libs --cflags taglib +``` + +You can use pkg-config from CMake, however, relocation with `--define-prefix` +is not supported. + +``` +cmake_minimum_required(VERSION 3.6.0) +project(taglib-client) +find_package(PkgConfig) +pkg_check_modules(TAGLIB REQUIRED IMPORTED_TARGET taglib) +add_executable(tagreader tagreader.cpp) +target_link_libraries(tagreader PkgConfig::TAGLIB) +``` + +#### Framework on macOS + +On macOS, you might want to build a framework that can be easily integrated into your application. If you set the BUILD_FRAMEWORK option on, it will compile TagLib as a framework. For example, the following command can be used to build -a framework with Mac OS X 10.10 as the deployment target: +a framework with macOS 10.10 as the deployment target: mkdir build; cd build cmake .. -DCMAKE_BUILD_TYPE=Release \ @@ -51,176 +216,217 @@ For a 10.10 static library, use: After `make`, and `make install`, add `libtag.` to your XCode project, and add the include folder to the project's User Header Search Paths. -Windows -------- - -It's Windows ... Systems vary! -This means you need to adjust things to suit your system, especially paths. - -Tested with: -* Microsoft Visual Studio 2010, 2015, 2017 -* Microsoft C++ Build Tools 2015, 2017 (standalone packages not requiring Visual Studio) -* GCC by mingw-w64.sf.net v4.6.3 (Strawberry Perl 32b) -* MinGW32-4.8.0 - -Requirements: -* Tool chain, build environment, whatever ya want to call it ... - Installed and working. -* CMake program (available at: www.cmake.org). - Installed and working. - -Optional: -* Zlib library. - Available in some tool chains, not all. - Search the web, take your choice. - - Useful configuration options used with CMake (GUI and/or command line): - Any of the `ZLIB_` variables may be used at the command line, `ZLIB_ROOT` is only - available on the command line. - - | option | description | - | ----------------------- | ----------- | - | `WITH_ZLIB=` | Whether to build with ZLib | - | `ZLIB_ROOT=` | Where to find ZLib's root directory. Assumes parent of: `\include` and `\lib.`| - | `ZLIB_INCLUDE_DIR=` | Where to find ZLib's Include directory.| - | `ZLIB_LIBRARY=` | Where to find ZLib's Library.| - | `ZLIB_SOURCE=` | Where to find ZLib's Source Code. Alternative to `ZLIB_INCLUDE_DIR` and `ZLIB_LIBRARY`.| - | `CMAKE_INSTALL_PREFIX=` | Where to install Taglib. | - | `CMAKE_BUILD_TYPE=` | Release, Debug, etc ... (Not available in MSVC) | - -The easiest way is at the command prompt (Visual C++ command prompt for MSVS users – batch file and/or shortcuts are your friends). - -1. **Build the Makefiles:** - - Replace "GENERATOR" with your needs. - * For MSVS: `Visual Studio XX YYYY`, e.g. `Visual Studio 14 2015`. - - **Note**: As Visual Studio 2017 supports CMake, you can skip this step and open the taglib - folder in VS instead. - * For MinGW: `MinGW Makefiles` - - C:\GitRoot\taglib> cmake -G "GENERATOR" -DCMAKE_INSTALL_PREFIX=C:\Libraries\taglib - - Or use the CMake GUI: - 1. Open CMake GUI. - 2. Set paths: *Where is the source code* and *Where to build the binaries*. - - In the example, both would be: `C:\GitRoot\taglib` - 3. Tick: Advanced - 4. Select: Configure - 5. Select: Generator - 6. Tick: Use default native compilers - 7. Select: Finish - Wait until done. - 8. If using ZLib, Scroll down. - (to the bottom of the list of options ... should go over them all) - 1. Edit: `ZLIB_INCLUDE_DIR` - 2. Edit: `ZLIB_LIBRARY` - 9. Select: Generate - -2. **Build the project** - * MSVS: - - C:\GitRoot\taglib> msbuild all_build.vcxproj /p:Configuration=Release - OR (Depending on MSVS version or personal choice) - - C:\GitRoot\taglib> devenv all_build.vcxproj /build Release - OR in the MSVS GUI: - 1. Open MSVS. - 2. Open taglib solution. - 3. Set build type to: Release (look in the toolbars) - 4. Hit F7 to build the solution. (project) - * MinGW: - - C:\GitRoot\taglib> gmake - - OR (Depending on MinGW install) - - C:\GitRoot\taglib> mingw32-make - -3. **Install the project** - - (Change `install` to `uninstall` to uninstall the project) - * MSVS: - - C:\GitRoot\taglib> msbuild install.vcxproj - OR (Depending on MSVC version or personal choice) - - C:\GitRoot\taglib> devenv install.vcxproj - - Or in the MSVS GUI: - 1. Open project. - 2. Open Solution Explorer. - 3. Right Click: INSTALL - 4. Select: Project Only - 5. Select: Build Only INSTALL - * MinGW: - - C:\GitRoot\taglib> gmake install - OR (Depending on MinGW install) - - C:\GitRoot\taglib> mingw32-make install - - -To build a static library, set the following two options with CMake: - - -DBUILD_SHARED_LIBS=OFF -DENABLE_STATIC_RUNTIME=ON +## Windows + +### Using Visual Studio Build Tools + +For this example, we assume that you have the Visual Studio Build Tools 2022 +installed. Additionally, you need [cmake](https://cmake.org/), which can be +installed for example using [scoop](https://scoop.sh/) with +`scoop install cmake`. + +#### Building TagLib (MSVC) + +You can build and install the dependencies +[utf8cpp](https://github.com/nemtrif/utfcpp) and optionally +[zlib](https://www.zlib.net/) and +[CppUnit](https://wiki.documentfoundation.org/Cppunit) yourself, but it is +probably easier using a package manager such as [vcpkg](https://vcpkg.io/), +which can be installed using `scoop install vcpkg` and then install the +dependencies using `vcpkg install utfcpp zlib cppunit`. + +Now you can build TagLib from PowerShell. + +``` +# Adapt these environment variables to your directories +$env:TAGLIB_SRC_DIR = "${env:HOMEDRIVE}${env:HOMEPATH}/projects/taglib/src/taglib" +$env:TAGLIB_DST_DIR = "${env:HOMEDRIVE}${env:HOMEPATH}/projects/taglib/src/msvs_vcpkg_build" +cd $env:TAGLIB_SRC_DIR +cmake -B $env:TAGLIB_DST_DIR -DBUILD_SHARED_LIBS=ON -DVISIBILITY_HIDDEN=ON ` + -DBUILD_TESTING=ON -DBUILD_EXAMPLES=ON -DBUILD_BINDINGS=ON ` + -DCMAKE_BUILD_TYPE=Release ` + -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" ` + -G "Visual Studio 17 2022" +cmake --build $env:TAGLIB_DST_DIR --config Release + +# Add directories containing DLL dependencies to path +$env:Path += -join(";$env:TAGLIB_DST_DIR\taglib\Release;", +"$env:TAGLIB_DST_DIR\bindings\c\Release;", +"$env:VCPKG_ROOT\packages\cppunit_x64-windows\bin;", +"$env:VCPKG_ROOT\packages\utfcpp_x64-windows\bin;", +"$env:VCPKG_ROOT\packages\zlib_x64-windows\bin") +cmake --build $env:TAGLIB_DST_DIR --config Release --target check + +# Install to \pkg folder on current drive +cmake --install $env:TAGLIB_DST_DIR --config Release --prefix /pkg --strip + +# Static library +$env:TAGLIB_DST_DIR = "C:/Users/fle/projects/taglib/src/msvs_vcpkg_static_build" +cmake -B $env:TAGLIB_DST_DIR -DBUILD_SHARED_LIBS=OFF -DVISIBILITY_HIDDEN=ON ` + -DBUILD_TESTING=ON -DBUILD_EXAMPLES=ON -DBUILD_BINDINGS=ON ` + -DCMAKE_BUILD_TYPE=Release ` + -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" ` + -G "Visual Studio 17 2022" +cmake --build $env:TAGLIB_DST_DIR --config Release + +cmake --build $env:TAGLIB_DST_DIR --config Release --target check + +# Install to \pkg_static folder on current drive +cmake --install $env:TAGLIB_DST_DIR --config Release --prefix /pkg_static --strip +``` Including `ENABLE_STATIC_RUNTIME=ON` indicates you want TagLib built using the static runtime library, rather than the DLL form of the runtime. -Unit Tests ----------- - -If you want to run the test suite to make sure TagLib works properly on your -system, you need to have cppunit installed. To build the tests, include -the option `-DBUILD_TESTING=ON` when running cmake. - -The test suite has a custom target in the build system, so you can run -the tests using make: - - make check - -Windows MinGW: - -* Get cppunit from https://www.freedesktop.org/wiki/Software/cppunit/ -* Build it for MinGW: - - `./autogen.sh` - - `./configure --disable-shared` - - `mingw32-make; mingw32-make install DESTDIR=/path/to/install/dir` -* Build TagLib with testing enabled: - - ``` - cmake -G "MinGW Makefiles" -DBUILD_TESTING=ON -DBUILD_EXAMPLES=ON -DBUILD_SHARED_LIBS=OFF \ - -DCPPUNIT_INCLUDE_DIR=/path/to/cppunit/include \ - -DCPPUNIT_LIBRARIES=/path/to/cppunit/lib/libcppunit.a \ - -DCPPUNIT_INSTALLED_VERSION=1.15.1 - ``` - - `mingw32-make` - - `mingw32-make check` - -Windows MSVS: - -* Get cppunit from https://www.freedesktop.org/wiki/Software/cppunit/ -* Build it in Visual Studio: - - Open examples/examples2008.sln, convert all, do not overwrite. - - Set architecture to x64, build configuration, e.g. Debug DLL. - - It may fail, but the needed libraries should be available in src\cppunit\DebugDll. -* Build TagLib with testing enabled: - - ``` - cmake -G "Visual Studio 16 2019" -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON -DBUILD_EXAMPLES=ON - -DBUILD_SHARED_LIBS=OFF -DENABLE_STATIC_RUNTIME=ON - -DCPPUNIT_INCLUDE_DIR=\path\to\cppunit\include - -DCPPUNIT_LIBRARIES=\path\to\cppunit\DebugDll\cppunitd_dll.lib - -DCPPUNIT_INSTALLED_VERSION=1.15.1 - ``` - - `msbuild all_build.vcxproj /p:Configuration=Debug` - - `path %path%;\path\to\cppunit\DebugDll` - - `tests\Debug\test_runner.exe` - -macOS: - -* Install cppunit using a package manager, e.g. `brew install cppunit` -* Build TagLib with testing enabled: - - `cmake -DBUILD_TESTS=ON -DBUILD_EXAMPLES=ON -DBUILD_SHARED_LIBS=OFF` - - `make` - - `make check` +#### Building a Project Using TagLib (MSVC) + +As an example for an external application using TagLib, we create a folder +taglib-client and copy the file tagreader.cpp from the examples folder +of the TagLib sources into it. We then add this simple CMakeLists.txt. + +``` +cmake_minimum_required(VERSION 3.5.0) +project(taglib-client) +set(CMAKE_CXX_STANDARD 17) +find_package(ZLIB) +find_package(TagLib 2.0.0 REQUIRED) +add_executable(tagreader tagreader.cpp) +target_link_libraries(tagreader TagLib::tag) +``` + +To build into a folder build inside this directory, just run + +``` +# Set this to the path where TagLib is installed +$env:TAGLIB_PREFIX = "/pkg" +cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="$env:TAGLIB_PREFIX" ` + -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake" ` + -G "Visual Studio 17 2022" +cmake --build build --config Release + +# Add directories containing DLL dependencies to path +$env:Path += ";$env:TAGLIB_PREFIX\bin;$env:VCPKG_ROOT\packages\zlib_x64-windows\bin" +build\Release\tagreader /path/to/audio-file +``` + +To use the C-bindings with tagreader_c.c, you can change the last two lines in +CMakeLists.txt to + +``` +add_executable(tagreader_c tagreader_c.c) +target_link_libraries(tagreader_c TagLib::tag_c) +``` + +If you link against a static TagLib, you have to adapt the installation path +(e.g. "/pkg_static") and add the following line to CMakeLists.txt + +``` +target_compile_definitions(tagreader_c PRIVATE TAGLIB_STATIC) +``` + +### Using MSYS2 + +#### Building TagLib (MSYS2) + +To build TagLib using Clang from MSYS, install [msys2](https://www.msys2.org/), +then start the MSYS CLANG64 shell and install the dependencies as they are +specified in the [MSYS recipe for TagLib]( +https://packages.msys2.org/package/mingw-w64-clang-x86_64-taglib?repo=clang64). + +``` +pacman -Suy +pacman -S mingw-w64-clang-x86_64-gcc-libs mingw-w64-clang-x86_64-zlib \ + mingw-w64-clang-x86_64-cc mingw-w64-clang-x86_64-cmake \ + mingw-w64-clang-x86_64-cppunit mingw-w64-clang-x86_64-ninja +``` + +Then you can build TagLib from the MSYS CLANG64 Bash. + +``` +# Adapt these environment variables to your directories +TAGLIB_SRC_DIR=$HOME/projects/taglib/src/taglib +TAGLIB_DST_DIR=$HOME/projects/taglib/src/msys_build +cd $TAGLIB_SRC_DIR +cmake -B $TAGLIB_DST_DIR -DBUILD_SHARED_LIBS=ON -DVISIBILITY_HIDDEN=ON \ + -DBUILD_TESTING=ON -DBUILD_EXAMPLES=ON -DBUILD_BINDINGS=ON \ + -DCMAKE_BUILD_TYPE=Release -G Ninja +cmake --build $TAGLIB_DST_DIR --config Release + +PATH=$PATH:/clang64/bin:$TAGLIB_DST_DIR/taglib:$TAGLIB_DST_DIR/bindings/c \ + cmake --build $TAGLIB_DST_DIR --config Release --target check + +# Install to /pkg_msys folder inside MSYS root (e.g. C:/msys64/pkg_msys/) +cmake --install $TAGLIB_DST_DIR --config Release --prefix /pkg_msys --strip +``` + +#### Building a Project Using TagLib (MSYS2) + +As an example for an external application using TagLib, we create a folder +taglib-client and copy the file tagreader.cpp from the examples folder +of the TagLib sources into it. We then add this simple CMakeLists.txt. + +``` +cmake_minimum_required(VERSION 3.5.0) +project(taglib-client) +set(CMAKE_CXX_STANDARD 17) +find_package(ZLIB) +find_package(TagLib 2.0.0 REQUIRED) +add_executable(tagreader tagreader.cpp) +target_link_libraries(tagreader TagLib::tag) +``` + +To build into a folder build_msys inside this directory, just run + +``` +# Set this to the path where TagLib is installed +TAGLIB_PREFIX=/pkg_msys +cmake -B build_msys -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=$TAGLIB_PREFIX -G Ninja +cmake --build build_msys --config Release + +PATH=$PATH:$TAGLIB_PREFIX/bin + build_msys/tagreader /path/to/audio-file +``` + +To use the C-bindings with tagreader_c.c, you can change the last two lines in +CMakeLists.txt to + +``` +add_executable(tagreader_c tagreader_c.c) +target_link_libraries(tagreader_c TagLib::tag_c) +``` + +### Using MinGW + +The instructions for MSYS2 can also be used to build with MinGW. You could use +Git Bash together with the MinGW provided by Qt. + +``` +# Adapt these environment variables to your directories +PATH=$PATH:/c/Qt/Tools/mingw1120_64/bin +TAGLIB_SRC_DIR=$HOME/projects/taglib/src/taglib +TAGLIB_DST_DIR=$HOME/projects/taglib/src/mingw_build +cd $TAGLIB_SRC_DIR +cmake -B $TAGLIB_DST_DIR -DBUILD_SHARED_LIBS=ON -DVISIBILITY_HIDDEN=ON \ + -DBUILD_EXAMPLES=ON -DBUILD_BINDINGS=ON -DWITH_ZLIB=OFF \ + -DCMAKE_BUILD_TYPE=Release -G 'MinGW Makefiles' +cmake --build $TAGLIB_DST_DIR --config Release + +PATH=$PATH:$TAGLIB_DST_DIR/taglib \ + $TAGLIB_DST_DIR/examples/tagreader /path/to/audio-file + +# Install to C:\pkg_mingw +cmake --install $TAGLIB_DST_DIR --config Release --prefix /c/pkg_mingw --strip +``` + +The installed package can then be used by other projects. + +``` +TAGLIB_PREFIX=/c/pkg_mingw +cmake -B build_mingw -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_INSTALL_PREFIX=$TAGLIB_PREFIX -G 'MinGW Makefiles' +cmake --build build_mingw --config Release + +PATH=$PATH:$TAGLIB_PREFIX/bin + build_mingw/tagreader /path/to/audio-file +``` diff --git a/taglib/toolkit/propertymapping.dox b/taglib/toolkit/propertymapping.dox new file mode 100644 index 000000000..7a87f612c --- /dev/null +++ b/taglib/toolkit/propertymapping.dox @@ -0,0 +1,112 @@ +/*! +\page p_propertymapping Mapping of Properties to Various Formats + +- If no mapping is given for an %ID3v2 tag, a TXXX frame will be used with the + key as a description. +- Vorbis Comments are not included in the table because they use the names from + the *Key* column. +- %APE tags will also use these keys unless another name can be found in its column. + +| Key | %ID3v2 | %RIFF | %MP4 | %APE | %ASF | +| -------------------------- | ------ | ----- | -------------------------------------------------------- | ----------------------- | --------------------------------- | +| ACOUSTID_FINGERPRINT | | | | | Acoustid/Fingerprint | +| ACOUSTID_ID | | | | | Acoustid/Id | +| ALBUM | TALB | IPRD | ©alb | | WM/AlbumTitle | +| ALBUMARTIST | TPE2 | | aART | ALBUM ARTIST | WM/AlbumArtist | +| ALBUMARTISTSORT | TSO2 | | soaa | | WM/AlbumArtistSortOrder | +| ALBUMSORT | TSOA | | soal | | WM/AlbumSortOrder | +| ARRANGER | | IENG | | | | +| ARTIST | TPE1 | IART | ©ART | | | +| ARTISTS | | | \----:com.apple.iTunes:ARTISTS | | WM/ARTISTS | +| ARTISTSORT | TSOP | | soar | | WM/ArtistSortOrder | +| ARTISTWEBPAGE | WOAR | IBSU | | | WM/AuthorURL | +| ASIN | | | \----:com.apple.iTunes:ASIN | | | +| AUDIOSOURCEWEBPAGE | WOAS | | | | ASIN | +| BARCODE | | | \----:com.apple.iTunes:BARCODE | | WM/Barcode | +| BPM | TBPM | IBPM | tmpo | | WM/BeatsPerMinute | +| CATALOGNUMBER | | | \----:com.apple.iTunes:CATALOGNUMBER | | WM/CatalogNo | +| COMMENT | COMM | ICMT | ©cmt | | | +| COMPILATION | TCMP | | cpil | | | +| COMPOSER | TCOM | IMUS | ©wrt | | WM/Composer | +| COMPOSERSORT | TSOC | | soco | | | +| CONDUCTOR | TPE3 | | \----:com.apple.iTunes:CONDUCTOR | | WM/Conductor | +| COPYRIGHT | TCOP | ICOP | cprt | | | +| COPYRIGHTURL | WCOP | | | | | +| DATE | TDRC | ICRD | ©day | YEAR | WM/Year | +| DISCNUMBER | TPOS | | disk | DISC | WM/PartOfSet | +| DISCSUBTITLE | TSST | PRT1 | \----:com.apple.iTunes:DISCSUBTITLE | | WM/SetSubTitle | +| DJMIXER | | | \----:com.apple.iTunes:DJMIXER | | | +| ENCODEDBY | TENC | ITCH | ©too | | WM/EncodedBy | +| ENCODING | TSSE | ISFT | | | WM/EncodingSettings | +| ENCODINGTIME | TDEN | IDIT | | | | +| ENGINEER | | | \----:com.apple.iTunes:ENGINEER | | | +| FILETYPE | TFLT | | | | | +| FILEWEBPAGE | WOAF | | | | | +| GAPLESSPLAYBACK | | | pgap | | | +| GENRE | TCON | IGNR | ©gen | | WM/Genre | +| GROUPING | GRP1 | | ©grp | | | +| INITIALKEY | TKEY | | | | WM/InitialKey | +| INVOLVEDPEOPLE | TIPL | | | | | +| ISRC | TSRC | ISRC | \----:com.apple.iTunes:ISRC | | WM/ISRC | +| LABEL | TPUB | IPUB | \----:com.apple.iTunes:LABEL | | WM/Publisher | +| LANGUAGE | TLAN | ILNG | \----:com.apple.iTunes:LANGUAGE | | WM/Language | +| LENGTH | TLEN | | \----:com.apple.iTunes:LYRICIST | | | +| LICENSE | | | \----:com.apple.iTunes:LICENSE | | | +| LYRICIST | TEXT | IWRI | | | WM/Writer | +| LYRICS | USLT | | ©lyr | | WM/Lyrics | +| MEDIA | TMED | IMED | \----:com.apple.iTunes:MEDIA | | WM/Media | +| MIXER | | | \----:com.apple.iTunes:MIXER | | | +| MOOD | TMOO | | \----:com.apple.iTunes:MOOD | | WM/Mood | +| MOVEMENTCOUNT | | | ©mvc | | | +| MOVEMENTNAME | MVNM | | ©mvn | | | +| MOVEMENTNUMBER | MVIN | | ©mvi | | | +| MUSICBRAINZ_ALBUMID | | | \----:com.apple.iTunes:MusicBrainz Album Id | | MusicBrainz/Album Id | +| MUSICBRAINZ_ALBUMARTISTID | | | \----:com.apple.iTunes:MusicBrainz Album Artist Id | | MusicBrainz/Album Artist Id | +| MUSICBRAINZ_ARTISTID | | | \----:com.apple.iTunes:MusicBrainz Artist Id | | MusicBrainz/Artist Id | +| MUSICBRAINZ_RELEASEGROUPID | | | \----:com.apple.iTunes:MusicBrainz Release Group Id | | MusicBrainz/Release Group Id | +| MUSICBRAINZ_RELEASETRACKID | | | \----:com.apple.iTunes:MusicBrainz Release Track Id | | MusicBrainz/Release Track Id | +| MUSICBRAINZ_TRACKID | | | \----:com.apple.iTunes:MusicBrainz Track Id | | MusicBrainz/Track Id | +| MUSICBRAINZ_WORKID | | | \----:com.apple.iTunes:MusicBrainz Work Id | | MusicBrainz/Work Id | +| MUSICIANCREDITS | TMCL | | | | | +| MUSICIP_PUID | | | | | MusicIP/PUID | +| ORIGINALALBUM | TOAL | | | | WM/OriginalAlbumTitle | +| ORIGINALARTIST | TOPE | | | | WM/OriginalArtist | +| ORIGINALDATE | TDOR | | \----:com.apple.iTunes:ORIGINALDATE | | WM/OriginalReleaseYear | +| ORIGINALFILENAME | TOFN | | | | WM/OriginalFilename | +| ORIGINALLYRICIST | TOLY | | | | WM/OriginalLyricist | +| OWNER | TOWN | | ownr | | | +| PAYMENTWEBPAGE | WPAY | | | | | +| PERFORMER | | ISTR | | | | +| PLAYLISTDELAY | TDLY | | | | | +| PODCAST | PCST | | pcst | | | +| PODCASTCATEGORY | TCAT | | catg | | | +| PODCASTDESC | TDES | | desc | | | +| PODCASTID | TGID | | egid | | | +| PODCASTURL | WFED | | purl | | | +| PRODUCEDNOTICE | TPRO | | | | | +| PRODUCER | | | \----:com.apple.iTunes:PRODUCER | | WM/Producer | +| PUBLISHERWEBPAGE | WPUB | | | | | +| RADIOSTATION | TRSN | | | | | +| RADIOSTATIONOWNER | TRSO | | | | | +| RADIOSTATIONWEBPAGE | WORS | | | | | +| RELEASECOUNTRY | | ICNT | \----:com.apple.iTunes:MusicBrainz Album Release Country | | MusicBrainz/Album Release Country | +| RELEASEDATE | TDRL | | \----:com.apple.iTunes:RELEASEDATE | | | +| RELEASESTATUS | | | \----:com.apple.iTunes:MusicBrainz Album Status | MUSICBRAINZ_ALBUMSTATUS | MusicBrainz/Album Status | +| RELEASETYPE | | | \----:com.apple.iTunes:MusicBrainz Album Type | MUSICBRAINZ_ALBUMTYPE | MusicBrainz/Album Type | +| REMIXER | TPE4 | IEDT | \----:com.apple.iTunes:REMIXER | MIXARTIST | WM/ModifiedBy | +| SCRIPT | | | \----:com.apple.iTunes:SCRIPT | | WM/Script | +| SHOWSORT | | | sosn | | | +| SHOWWORKMOVEMENT | | | shwm | | | +| SUBTITLE | TIT3 | | \----:com.apple.iTunes:SUBTITLE | | WM/SubTitle | +| TAGGINGDATE | TDTG | | | | | +| TITLE | TIT2 | INAM | ©nam | | | +| TITLESORT | TSOT | | sonm | | WM/TitleSortOrder | +| TRACKNUMBER | TRCK | IPRT | trkn | TRACK | WM/TrackNumber | +| TVEPISODE | | | tves | | | +| TVEPISODEID | | | tven | | | +| TVNETWORK | | | tvnn | | | +| TVSEASON | | | tvsn | | | +| TVSHOW | | | tvsh | | | +| URL | WXXX | | | | | +| WORK | TIT1 | | ©wrk | | WM/ContentGroupDescription | +*/ diff --git a/taglib/toolkit/taglib.h b/taglib/toolkit/taglib.h index c212968ff..8d65c1ea0 100644 --- a/taglib/toolkit/taglib.h +++ b/taglib/toolkit/taglib.h @@ -95,7 +95,7 @@ namespace TagLib { * - A clean, high level, C++ API to handling audio meta data. * - Format specific APIs for advanced API users. * - ID3v1, ID3v2, APE, FLAC, Xiph, iTunes-style MP4 and WMA tag formats. - * - MP3, MPC, FLAC, MP4, ASF, AIFF, WAV, TrueAudio, WavPack, Ogg FLAC, Ogg Vorbis, Speex and Opus file formats. + * - MP3, MPC, FLAC, MP4, ASF, AIFF, WAV, DSF, DFF, TrueAudio, WavPack, Ogg FLAC, Ogg Vorbis, Speex and Opus file formats. * - Basic audio file properties such as length, sample rate, etc. * - Long term binary and source compatibility. * - Extensible design, notably the ability to add other formats or extend current formats as a library user. @@ -126,10 +126,14 @@ namespace TagLib { * Please see the TagLib website for the latest * downloads. * - * TagLib can be built using the CMake build system. TagLib installs a taglib-config and pkg-config file to + * TagLib can be built using the CMake build system. TagLib installs a CMake + * configuration and a taglib-config and pkg-config file to * make it easier to integrate into various build systems. Note that TagLib's include install directory \e must * be included in the header include path. Simply adding will \e not work. * + * Detailed instructions about building TagLib itself and building with TagLib + * can be found in INSTALL.md + * * \section start Getting Started * * TagLib provides both simple, abstract APIs which make it possible to ignore the differences between tagging @@ -146,8 +150,7 @@ namespace TagLib { * * Here's a very simple example with TagLib: * - * \code - * + * \code {.cpp} * TagLib::FileRef f("Latex Solar Beef.mp3"); * TagLib::String artist = f.tag()->artist(); // artist == "Frank Zappa" * @@ -159,10 +162,63 @@ namespace TagLib { * * g.tag()->setTrack(1); * g.save(); + * \endcode + * + * If the basic tag interface, which provides methods like + * \link TagLib::Tag::title() title() \endlink, + * \link TagLib::Tag::artist() artist() \endlink, + * \link TagLib::Tag::album() album() \endlink, + * \link TagLib::Tag::comment() comment() \endlink, + * \link TagLib::Tag::genre() genre() \endlink, + * \link TagLib::Tag::year() year() \endlink, + * \link TagLib::Tag::track() track() \endlink + * and the corresponding setters, is not enough, the + * \link TagLib::PropertyMap PropertyMap \endlink interface + * offers a flexible abstraction for textual metadata. + * See \ref p_propertymapping for details about the mapping of tags to properties. + * + * \code {.cpp} + * TagLib::PropertyMap props = f.properties(); + * TagLib::StringList artists = props["ARTIST"]; + * artists.append("Jim Pons"); + * props["ARTIST"] = artists; + * f.setProperties(props); + * f.save(); + * \endcode + * + * An additional \link FileRef::complexProperties() abstraction \endlink is + * provided to handle complex (i.e. non textual) properties. + * + * \code {.cpp} + * TagLib::ByteVector data = ...; + * f.setComplexProperties("PICTURE", { + * { + * {"data", data}, + * {"pictureType", "Front Cover"}, + * {"mimeType", "image/jpeg"} + * } + * }); + * \endcode * + * Finally, for full control, there are specific types for all supported metadata formats. + * + * \code {.cpp} + * if(auto file = dynamic_cast(f.file())) { + * if(auto id3v2Tag = file->ID3v2Tag()) { + * auto frames = id3v2Tag->frameList("SYLT"); + * if(!frames.isEmpty()) { + * if(auto syltFrame = dynamic_cast( + * frames.front())) { + * auto text = syltFrame->synchedText(); + * // ... + * } + * } + * } + * } * \endcode * - * More examples can be found in the \e examples directory of the source distribution. + * More examples can be found in the + * examples directory of the source distribution. * * \section Contact * diff --git a/taglib/toolkit/tpropertymap.h b/taglib/toolkit/tpropertymap.h index 5030176df..5f2768228 100644 --- a/taglib/toolkit/tpropertymap.h +++ b/taglib/toolkit/tpropertymap.h @@ -46,6 +46,9 @@ namespace TagLib { * and a nonempty list of corresponding values, each value being an arbitrary * unicode String. * + * See \ref p_propertymapping for the mapping of the different formats to + * properties. + * * Note that most metadata formats pose additional conditions on the tag keys. The * most popular ones (Vorbis, APE, ID3v2) should support all ASCII only words of * length between 2 and 16.