From 9975905fafcf49c829e7b79cd66e9da3aab509a8 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Wed, 9 Mar 2022 14:29:00 +0100 Subject: [PATCH 01/17] output/PipeWire: initialize field "stream" in Open() Must be initialized for the check in SetVolume(). --- NEWS | 2 ++ src/output/plugins/PipeWireOutputPlugin.cxx | 2 ++ 2 files changed, 4 insertions(+) diff --git a/NEWS b/NEWS index a78b30fa0..fb4591849 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,8 @@ ver 0.23.6 (not yet released) * decoder - opus: fix "readpicture" on Opus files +* output + - pipewire: fix crash bug if setting volume before playback starts ver 0.23.5 (2021/12/01) * protocol diff --git a/src/output/plugins/PipeWireOutputPlugin.cxx b/src/output/plugins/PipeWireOutputPlugin.cxx index 02f66cddb..bf5155a5b 100644 --- a/src/output/plugins/PipeWireOutputPlugin.cxx +++ b/src/output/plugins/PipeWireOutputPlugin.cxx @@ -336,6 +336,8 @@ PipeWireOutput::Enable() throw MakeErrno("pw_thread_loop_new() failed"); pw_thread_loop_start(thread_loop); + + stream = nullptr; } void From 8f84e1befdc346d787f8423ef91c99062b6460d3 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 14 Mar 2022 13:58:37 +0100 Subject: [PATCH 02/17] decoder/plugins/FfmpegIo: return AVERROR_EOF at end of file This part of the AVIOContext API is not documented :-( Closes https://github.com/MusicPlayerDaemon/MPD/issues/1448 --- NEWS | 1 + src/decoder/plugins/FfmpegIo.cxx | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index fb4591849..74c5de4e4 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,6 @@ ver 0.23.6 (not yet released) * decoder + - ffmpeg: fix end-of-file check (update stuck at empty files) - opus: fix "readpicture" on Opus files * output - pipewire: fix crash bug if setting volume before playback starts diff --git a/src/decoder/plugins/FfmpegIo.cxx b/src/decoder/plugins/FfmpegIo.cxx index f505dbdec..9ce80f4b7 100644 --- a/src/decoder/plugins/FfmpegIo.cxx +++ b/src/decoder/plugins/FfmpegIo.cxx @@ -35,7 +35,11 @@ AvioStream::~AvioStream() inline int AvioStream::Read(void *dest, int size) { - return decoder_read(client, input, dest, size); + const auto nbytes = decoder_read(client, input, dest, size); + if (nbytes == 0) + return AVERROR_EOF; + + return nbytes; } inline int64_t From 5ad1a01d7ade6e6220f392c709808e3334cd01a7 Mon Sep 17 00:00:00 2001 From: jcorporation Date: Sun, 13 Mar 2022 17:08:58 +0100 Subject: [PATCH 03/17] Remove bmp, tiff and add webp for coverimage filenames - supporting bmp and tiff seems outdated - webp is more widely used for coverimages --- NEWS | 2 ++ src/command/FileCommands.cxx | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 74c5de4e4..daa2b77a7 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,6 @@ ver 0.23.6 (not yet released) +* protocol + - support filename "cover.webp" for "albumart" command * decoder - ffmpeg: fix end-of-file check (update stuck at empty files) - opus: fix "readpicture" on Opus files diff --git a/src/command/FileCommands.cxx b/src/command/FileCommands.cxx index 006dedf28..c27eaeb79 100644 --- a/src/command/FileCommands.cxx +++ b/src/command/FileCommands.cxx @@ -160,8 +160,7 @@ find_stream_art(std::string_view directory, Mutex &mutex) static constexpr auto art_names = std::array { "cover.png", "cover.jpg", - "cover.tiff", - "cover.bmp", + "cover.webp", }; for(const auto name : art_names) { From ebae25d175eb31fbbadf8b0b2d079915ad40396d Mon Sep 17 00:00:00 2001 From: nick black Date: Mon, 28 Feb 2022 01:46:00 -0500 Subject: [PATCH 04/17] plugins/FfmpegIO: include libavutil/mem.h ffmpeg from current git master no longer exposes av_malloc() nor av_free() through other included headers. directly include libavutil/mem.h to fix compilation with (as-yet-unreleased) ffmpeg. --- src/decoder/plugins/FfmpegIo.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/decoder/plugins/FfmpegIo.cxx b/src/decoder/plugins/FfmpegIo.cxx index 9ce80f4b7..2e22d9599 100644 --- a/src/decoder/plugins/FfmpegIo.cxx +++ b/src/decoder/plugins/FfmpegIo.cxx @@ -21,6 +21,7 @@ #define __STDC_CONSTANT_MACROS #include "FfmpegIo.hxx" +#include "libavutil/mem.h" #include "../DecoderAPI.hxx" #include "input/InputStream.hxx" From aeaef855077384f4d669dc8013948a17b5ce38cc Mon Sep 17 00:00:00 2001 From: Richard Schorrig Date: Tue, 22 Feb 2022 21:05:41 +0100 Subject: [PATCH 05/17] WasapiOutputPlugin pause bug fix Wasapi output plugin won't start playing after being paused The cause is that the scope guard in the WASAPI work thread (WasapiOutputPlugin.cxx, function WasapiOutputThread::Work(), in the while (true) loop) is set up too 'late' in the execution. There is one condition ("if (data_in_frames >= buffer_size_in_frames)") when it is hit, the loop will continue without executing the scope guard. This scope guard is responsible for emptying the buffer again, and if the buffer is not emptied, the above mentioned condition will stay true. Closes https://github.com/MusicPlayerDaemon/MPD/issues/1451 --- NEWS | 1 + .../plugins/wasapi/WasapiOutputPlugin.cxx | 20 +++++++++---------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/NEWS b/NEWS index daa2b77a7..cdc114954 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,7 @@ ver 0.23.6 (not yet released) - opus: fix "readpicture" on Opus files * output - pipewire: fix crash bug if setting volume before playback starts + - wasapi: fix resume after pause ver 0.23.5 (2021/12/01) * protocol diff --git a/src/output/plugins/wasapi/WasapiOutputPlugin.cxx b/src/output/plugins/wasapi/WasapiOutputPlugin.cxx index bedd9f756..992dc2e67 100644 --- a/src/output/plugins/wasapi/WasapiOutputPlugin.cxx +++ b/src/output/plugins/wasapi/WasapiOutputPlugin.cxx @@ -471,6 +471,16 @@ try { } UINT32 write_in_frames = buffer_size_in_frames; + DWORD mode = 0; + AtScopeExit(&) { + render_client->ReleaseBuffer(write_in_frames, mode); + + if (!started) { + Start(client); + started = true; + } + }; + if (!is_exclusive) { UINT32 data_in_frames = GetCurrentPaddingFrames(client); @@ -481,7 +491,6 @@ try { } BYTE *data; - DWORD mode = 0; if (HRESULT result = render_client->GetBuffer(write_in_frames, &data); @@ -489,15 +498,6 @@ try { throw MakeHResultError(result, "Failed to get buffer"); } - AtScopeExit(&) { - render_client->ReleaseBuffer(write_in_frames, mode); - - if (!started) { - Start(client); - started = true; - } - }; - const UINT32 write_size = write_in_frames * frame_size; UINT32 new_data_size = 0; new_data_size = spsc_buffer.pop(data, write_size); From 2d705efe1ca8c85927b8ffa5e696e415014ad535 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 14 Mar 2022 14:29:20 +0100 Subject: [PATCH 06/17] python/build/libs.py: update libmpdclient to 2.20 --- python/build/libs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/build/libs.py b/python/build/libs.py index dd69d9780..a1fc60196 100644 --- a/python/build/libs.py +++ b/python/build/libs.py @@ -12,8 +12,8 @@ from build.boost import BoostProject from build.jack import JackProject libmpdclient = MesonProject( - 'https://www.musicpd.org/download/libmpdclient/2/libmpdclient-2.19.tar.xz', - '158aad4c2278ab08e76a3f2b0166c99b39fae00ee17231bd225c5a36e977a189', + 'https://www.musicpd.org/download/libmpdclient/2/libmpdclient-2.20.tar.xz', + '18793f68e939c3301e34d8fcadea1f7daa24143941263cecadb80126194e277d', 'lib/libmpdclient.a', ) From 878d9abeb741bc4a3723ab8bcce800b9bfbd2f9e Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 14 Mar 2022 14:29:58 +0100 Subject: [PATCH 07/17] python/build/libs.py: update libogg to 1.3.5 --- python/build/libs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/build/libs.py b/python/build/libs.py index a1fc60196..20c7e949b 100644 --- a/python/build/libs.py +++ b/python/build/libs.py @@ -18,8 +18,8 @@ libmpdclient = MesonProject( ) libogg = CmakeProject( - 'http://downloads.xiph.org/releases/ogg/libogg-1.3.4.tar.xz', - 'c163bc12bc300c401b6aa35907ac682671ea376f13ae0969a220f7ddf71893fe', + 'http://downloads.xiph.org/releases/ogg/libogg-1.3.5.tar.xz', + 'c4d91be36fc8e54deae7575241e03f4211eb102afb3fc0775fbbc1b740016705', 'lib/libogg.a', [ '-DBUILD_SHARED_LIBS=OFF', From c9530118a44ab80970374e2be4200277e4de2d02 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 14 Mar 2022 14:31:11 +0100 Subject: [PATCH 08/17] python/build/libs.py: update FLAC to 1.3.4 --- python/build/libs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/build/libs.py b/python/build/libs.py index 20c7e949b..f852e1341 100644 --- a/python/build/libs.py +++ b/python/build/libs.py @@ -43,8 +43,8 @@ opus = AutotoolsProject( ) flac = AutotoolsProject( - 'http://downloads.xiph.org/releases/flac/flac-1.3.3.tar.xz', - '213e82bd716c9de6db2f98bcadbc4c24c7e2efe8c75939a1a84e28539c4e1748', + 'http://downloads.xiph.org/releases/flac/flac-1.3.4.tar.xz', + '8ff0607e75a322dd7cd6ec48f4f225471404ae2730d0ea945127b1355155e737', 'lib/libFLAC.a', [ '--disable-shared', '--enable-static', From 7ef86cbf9ff3edc0d660012ba1699d3135f1556b Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 14 Mar 2022 14:35:12 +0100 Subject: [PATCH 09/17] python/build/libs.py: update FFmpeg to 5.0 --- python/build/libs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/build/libs.py b/python/build/libs.py index f852e1341..89d3576ae 100644 --- a/python/build/libs.py +++ b/python/build/libs.py @@ -151,8 +151,8 @@ gme = CmakeProject( ) ffmpeg = FfmpegProject( - 'http://ffmpeg.org/releases/ffmpeg-4.4.1.tar.xz', - 'eadbad9e9ab30b25f5520fbfde99fae4a92a1ae3c0257a8d68569a4651e30e02', + 'http://ffmpeg.org/releases/ffmpeg-5.0.tar.xz', + '51e919f7d205062c0fd4fae6243a84850391115104ccf1efc451733bc0ac7298', 'lib/libavcodec.a', [ '--disable-shared', '--enable-static', From 8a59493d963d155110243f7383633d7847815b84 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 14 Mar 2022 14:35:47 +0100 Subject: [PATCH 10/17] python/build/libs.py: update OpenSSL to 3.0.1 --- python/build/libs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/build/libs.py b/python/build/libs.py index 89d3576ae..8befabafd 100644 --- a/python/build/libs.py +++ b/python/build/libs.py @@ -380,8 +380,8 @@ ffmpeg = FfmpegProject( ) openssl = OpenSSLProject( - 'https://www.openssl.org/source/openssl-3.0.0.tar.gz', - '59eedfcb46c25214c9bd37ed6078297b4df01d012267fe9e9eee31f61bc70536', + 'https://www.openssl.org/source/openssl-3.0.1.tar.gz', + 'c311ad853353bce796edad01a862c50a8a587f62e7e2100ef465ab53ec9b06d1', 'include/openssl/ossl_typ.h', ) From c361e235ebef98e94b8f2ea1bc745acc73bf5593 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 14 Mar 2022 14:36:33 +0100 Subject: [PATCH 11/17] python/build/libs.py: update CURL to 7.82.0 --- python/build/libs.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/python/build/libs.py b/python/build/libs.py index 8befabafd..f4af05d9f 100644 --- a/python/build/libs.py +++ b/python/build/libs.py @@ -386,8 +386,8 @@ openssl = OpenSSLProject( ) curl = CmakeProject( - 'https://curl.se/download/curl-7.79.1.tar.xz', - '0606f74b1182ab732a17c11613cbbaf7084f2e6cca432642d0e3ad7c224c3689', + 'https://curl.se/download/curl-7.82.0.tar.xz', + '0aaa12d7bd04b0966254f2703ce80dd5c38dbbd76af0297d3d690cdce58a583c', 'lib/libcurl.a', [ '-DBUILD_CURL_EXE=OFF', @@ -415,7 +415,7 @@ curl = CmakeProject( '-DBUILD_TESTING=OFF', ], windows_configure_args=[ - '-DCMAKE_USE_SCHANNEL=ON', + '-DCURL_USE_SCHANNEL=ON', ], patches='src/lib/curl/patches', ) From 603bbe0afdf59de2e0d1723b9b8681d719e29900 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 14 Mar 2022 14:41:06 +0100 Subject: [PATCH 12/17] python/build/libs.py: update libnfs to 5.0.1 --- python/build/libs.py | 7 +++---- src/lib/nfs/patches/no_sprintf_s | 14 -------------- src/lib/nfs/patches/series | 1 - 3 files changed, 3 insertions(+), 19 deletions(-) delete mode 100644 src/lib/nfs/patches/no_sprintf_s delete mode 100644 src/lib/nfs/patches/series diff --git a/python/build/libs.py b/python/build/libs.py index f4af05d9f..ad8d03a54 100644 --- a/python/build/libs.py +++ b/python/build/libs.py @@ -421,8 +421,8 @@ curl = CmakeProject( ) libnfs = AutotoolsProject( - 'https://github.com/sahlberg/libnfs/archive/libnfs-4.0.0.tar.gz', - '6ee77e9fe220e2d3e3b1f53cfea04fb319828cc7dbb97dd9df09e46e901d797d', + 'https://github.com/sahlberg/libnfs/archive/libnfs-5.0.1.tar.gz', + '7ef445410b42f36b9bad426608b53ccb9ccca4101e545c383f564c11db672ca8', 'lib/libnfs.a', [ '--disable-shared', '--enable-static', @@ -433,8 +433,7 @@ libnfs = AutotoolsProject( '--disable-utils', '--disable-examples', ], - base='libnfs-libnfs-4.0.0', - patches='src/lib/nfs/patches', + base='libnfs-libnfs-5.0.1', autoreconf=True, ) diff --git a/src/lib/nfs/patches/no_sprintf_s b/src/lib/nfs/patches/no_sprintf_s deleted file mode 100644 index c2bce1466..000000000 --- a/src/lib/nfs/patches/no_sprintf_s +++ /dev/null @@ -1,14 +0,0 @@ -Index: libnfs-libnfs-4.0.0/include/win32/win32_compat.h -=================================================================== ---- libnfs-libnfs-4.0.0.orig/include/win32/win32_compat.h -+++ libnfs-libnfs-4.0.0/include/win32/win32_compat.h -@@ -133,7 +133,9 @@ struct pollfd { - - /* Wrapper macros to call misc. functions win32 is missing */ - #define poll(x, y, z) win32_poll(x, y, z) -+#ifndef __MINGW32__ - #define snprintf sprintf_s -+#endif - #define inet_pton(x,y,z) win32_inet_pton(x,y,z) - #define open(x, y, z) _open(x, y, z) - #ifndef lseek diff --git a/src/lib/nfs/patches/series b/src/lib/nfs/patches/series deleted file mode 100644 index d2e2667c9..000000000 --- a/src/lib/nfs/patches/series +++ /dev/null @@ -1 +0,0 @@ -no_sprintf_s From c83294916a004fea44c5ffddf9b27f79b9a0dbf8 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 14 Mar 2022 14:42:33 +0100 Subject: [PATCH 13/17] python/build/libs.py: update Boost to 1.78.0 --- python/build/libs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/build/libs.py b/python/build/libs.py index ad8d03a54..412ca5b92 100644 --- a/python/build/libs.py +++ b/python/build/libs.py @@ -444,7 +444,7 @@ jack = JackProject( ) boost = BoostProject( - 'https://boostorg.jfrog.io/artifactory/main/release/1.77.0/source/boost_1_77_0.tar.bz2', - 'fc9f85fc030e233142908241af7a846e60630aa7388de9a5fafb1f3a26840854', + 'https://boostorg.jfrog.io/artifactory/main/release/1.78.0/source/boost_1_78_0.tar.bz2', + '8681f175d4bdb26c52222665793eef08490d7758529330f98d3b29dd0735bccc', 'include/boost/version.hpp', ) From 71cd6e624824782baee257eaa0c95a922d153857 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 14 Mar 2022 15:07:48 +0100 Subject: [PATCH 14/17] lib/xiph/meson.build: define FLAC__NO_DLL for static libFLAC build (Windows) In libFLAC 0.3.4 (commit c9530118a44), the "dllimport" check has been changed from "_MSC_VER" to "_WIN32", and now the MPD build is affected by it. Defining FLAC__NO_DLL disables the use of "dllimport", which allows linking properly to the static libFLAC build. --- src/lib/xiph/meson.build | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/lib/xiph/meson.build b/src/lib/xiph/meson.build index 8786ac7e6..c39cee8d4 100644 --- a/src/lib/xiph/meson.build +++ b/src/lib/xiph/meson.build @@ -1,4 +1,11 @@ libflac_dep = dependency('flac', version: '>= 1.2', required: get_option('flac')) + +if is_windows + # Our Windows build generates a static libFLAC build + libflac_dep = declare_dependency(compile_args: '-DFLAC__NO_DLL', + dependencies: libflac_dep) +endif + libopus_dep = dependency('opus', required: get_option('opus')) if get_option('tremor').enabled() From 2aed7378ccc9b9abd9efae3417e15c44478e6556 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 14 Mar 2022 17:44:39 +0100 Subject: [PATCH 15/17] TagAny: support CUE tracks Closes https://github.com/MusicPlayerDaemon/MPD/issues/1482 --- NEWS | 1 + src/TagAny.cxx | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/NEWS b/NEWS index cdc114954..d1276ce49 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,7 @@ ver 0.23.6 (not yet released) * protocol - support filename "cover.webp" for "albumart" command + - support "readcomments" and "readpicture" on CUE tracks * decoder - ffmpeg: fix end-of-file check (update stuck at empty files) - opus: fix "readpicture" on Opus files diff --git a/src/TagAny.cxx b/src/TagAny.cxx index 6f875846e..2fd573fae 100644 --- a/src/TagAny.cxx +++ b/src/TagAny.cxx @@ -21,12 +21,16 @@ #include "TagStream.hxx" #include "TagFile.hxx" #include "tag/Generic.hxx" +#include "song/LightSong.hxx" +#include "db/Interface.hxx" #include "storage/StorageInterface.hxx" #include "client/Client.hxx" #include "protocol/Ack.hxx" #include "fs/AllocatedPath.hxx" #include "input/InputStream.hxx" #include "util/Compiler.h" +#include "util/ScopeExit.hxx" +#include "util/StringCompare.hxx" #include "util/UriExtract.hxx" #include "LocateUri.hxx" @@ -51,10 +55,67 @@ TagScanFile(const Path path_fs, TagHandler &handler) ScanGenericTags(path_fs, handler); } +#ifdef ENABLE_DATABASE + +/** + * Collapse "../" prefixes in a URI relative to the specified base + * URI. + */ +static std::string +ResolveUri(std::string_view base, const char *relative) +{ + while (true) { + const char *rest = StringAfterPrefix(relative, "../"); + if (rest == nullptr) + break; + + if (base == ".") + throw ProtocolError(ACK_ERROR_NO_EXIST, "Bad real URI"); + + base = PathTraitsUTF8::GetParent(base); + relative = rest; + } + + return PathTraitsUTF8::Build(base, relative); +} + +/** + * Look up the specified song in the database and return its + * (resolved) "real" URI. + */ +static std::string +GetRealSongUri(Client &client, std::string_view uri) +{ + const auto &db = client.GetDatabaseOrThrow(); + + const auto *song = db.GetSong(uri); + if (song == nullptr) + throw ProtocolError(ACK_ERROR_NO_EXIST, "No such song"); + + AtScopeExit(&db, song) { db.ReturnSong(song); }; + + if (song->real_uri == nullptr) + return {}; + + return ResolveUri(PathTraitsUTF8::GetParent(uri), song->real_uri); +} + +#endif + static void TagScanDatabase(Client &client, const char *uri, TagHandler &handler) { #ifdef ENABLE_DATABASE + const auto real_uri = GetRealSongUri(client, uri); + + if (!real_uri.empty()) { + uri = real_uri.c_str(); + + // TODO: support absolute paths? + if (uri_has_scheme(uri)) + return TagScanStream(uri, handler); + } + const Storage *storage = client.GetStorage(); if (storage == nullptr) { #else From 434869900ee45ea67cb58001c03afc6a116eadc6 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 14 Mar 2022 18:49:44 +0100 Subject: [PATCH 16/17] android/build.py: fix typo in error message Closes https://github.com/MusicPlayerDaemon/MPD/issues/1379 --- android/build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/build.py b/android/build.py index dd5bb2f5b..07e7d1ac3 100755 --- a/android/build.py +++ b/android/build.py @@ -13,7 +13,7 @@ android_abi = sys.argv[3] configure_args = sys.argv[4:] if not os.path.isfile(os.path.join(sdk_path, 'tools', 'android')): - print("SDK not found in", ndk_path, file=sys.stderr) + print("SDK not found in", sdk_path, file=sys.stderr) sys.exit(1) if not os.path.isdir(ndk_path): From f591193ddaa7f9bcb6c85ff5899517fc7b53e35a Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Mon, 14 Mar 2022 18:55:47 +0100 Subject: [PATCH 17/17] release v0.23.6 --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index d1276ce49..abf3251af 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,4 @@ -ver 0.23.6 (not yet released) +ver 0.23.6 (2022/03/14) * protocol - support filename "cover.webp" for "albumart" command - support "readcomments" and "readpicture" on CUE tracks