Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package mpd for openSUSE:Factory checked in 
at 2021-11-13 22:48:37
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/mpd (Old)
 and      /work/SRC/openSUSE:Factory/.mpd.new.1890 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "mpd"

Sat Nov 13 22:48:37 2021 rev:36 rq:931211 version:0.23.4

Changes:
--------
--- /work/SRC/openSUSE:Factory/mpd/mpd.changes  2021-11-06 18:21:31.464996826 
+0100
+++ /work/SRC/openSUSE:Factory/.mpd.new.1890/mpd.changes        2021-11-13 
22:49:07.509277537 +0100
@@ -1,0 +2,16 @@
+Fri Nov 12 23:12:23 UTC 2021 - ???????? ???????????? <[email protected]>
+
+- Updated to 0.23.4
+  * Changed file mpd-user.conf??? (disabled pid_file).
+  * Refreshed patch mpd-conf.patch.
+  * Removed patch mpd-service.patch.
+  * https://raw.githubusercontent.com/MusicPlayerDaemon/MPD/v0.23.4/NEWS
+  * protocol: add optional position parameter to "searchaddpl"
+  * decoder: ffmpeg: support libavcodec 59
+  * output: alsa: add option "thesycon_dsd_workaround" to work around device 
bug
+  * fix crash on debug builds if startup fails
+  * systemd:
+    * remove "RuntimeDirectory" directive because it caused problems
+    * ignore the "pid_file" setting if started as systemd service
+
+-------------------------------------------------------------------

Old:
----
  mpd-0.23.3.tar.xz
  mpd-0.23.3.tar.xz.sig
  mpd-service.patch

New:
----
  mpd-0.23.4.tar.xz
  mpd-0.23.4.tar.xz.sig

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ mpd.spec ++++++
--- /var/tmp/diff_new_pack.wxl7FG/_old  2021-11-13 22:49:07.909277844 +0100
+++ /var/tmp/diff_new_pack.wxl7FG/_new  2021-11-13 22:49:07.909277844 +0100
@@ -20,7 +20,7 @@
 %bcond_with    faad
 %bcond_without mpd_iso9660
 Name:           mpd
-Version:        0.23.3
+Version:        0.23.4
 Release:        0
 Summary:        Music Player Daemon
 License:        GPL-2.0-or-later
@@ -32,8 +32,7 @@
 Source4:        %{name}.firewalld
 Source5:        %{name}.tmpfiles.d
 Patch0:         %{name}-conf.patch
-Patch1:         %{name}-service.patch
-Patch2:         %{name}-sndfile.patch
+Patch1:         %{name}-sndfile.patch
 BuildRequires:  cmake
 BuildRequires:  gcc
 BuildRequires:  gcc-c++

++++++ mpd-0.23.3.tar.xz -> mpd-0.23.4.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/NEWS new/mpd-0.23.4/NEWS
--- old/mpd-0.23.3/NEWS 2021-10-31 18:13:10.000000000 +0100
+++ new/mpd-0.23.4/NEWS 2021-11-11 10:16:36.000000000 +0100
@@ -1,3 +1,17 @@
+ver 0.23.4 (2021/11/11)
+* protocol
+  - add optional position parameter to "searchaddpl"
+* decoder
+  - ffmpeg: support libavcodec 59
+* output
+  - alsa: add option "thesycon_dsd_workaround" to work around device bug
+* fix crash on debug builds if startup fails
+* systemd
+  - remove "RuntimeDirectory" directive because it caused problems
+  - ignore the "pid_file" setting if started as systemd service
+* Windows
+  - enable the "openmpt" decoder plugin
+
 ver 0.23.3 (2021/10/31)
 * protocol
   - add optional position parameter to "add" and "playlistadd"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/android/AndroidManifest.xml 
new/mpd-0.23.4/android/AndroidManifest.xml
--- old/mpd-0.23.3/android/AndroidManifest.xml  2021-10-31 18:13:10.000000000 
+0100
+++ new/mpd-0.23.4/android/AndroidManifest.xml  2021-11-11 10:16:36.000000000 
+0100
@@ -2,8 +2,8 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android";
           package="org.musicpd"
           android:installLocation="auto"
-          android:versionCode="63"
-          android:versionName="0.23.3">
+          android:versionCode="64"
+          android:versionName="0.23.4">
 
   <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="29"/>
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/doc/conf.py new/mpd-0.23.4/doc/conf.py
--- old/mpd-0.23.3/doc/conf.py  2021-10-31 18:13:10.000000000 +0100
+++ new/mpd-0.23.4/doc/conf.py  2021-11-11 10:16:36.000000000 +0100
@@ -38,7 +38,7 @@
 # built documents.
 #
 # The short X.Y version.
-version = '0.23.3'
+version = '0.23.4'
 # The full version, including alpha/beta/rc tags.
 #release = version + '~git'
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/doc/mpdconf.example 
new/mpd-0.23.4/doc/mpdconf.example
--- old/mpd-0.23.3/doc/mpdconf.example  2021-10-31 18:13:10.000000000 +0100
+++ new/mpd-0.23.4/doc/mpdconf.example  2021-11-11 10:16:36.000000000 +0100
@@ -26,22 +26,25 @@
 # files over an accepted protocol.
 #
 #db_file                       "~/.mpd/database"
-#
+
 # These settings are the locations for the daemon log files for the daemon.
-# These logs are great for troubleshooting, depending on your log_level
-# settings.
 #
 # The special value "syslog" makes MPD use the local syslog daemon. This
 # setting defaults to logging to syslog.
 #
-#log_file                      "~/.mpd/log"
+# If you use systemd, do not configure a log_file.  With systemd, MPD
+# defaults to the systemd journal, which is fine.
 #
+#log_file                      "~/.mpd/log"
+
 # This setting sets the location of the file which stores the process ID
 # for use of mpd --kill and some init scripts. This setting is disabled by
 # default and the pid file will not be stored.
 #
-#pid_file                      "~/.mpd/pid"
+# If you use systemd, do not configure a pid_file.
 #
+#pid_file                      "~/.mpd/pid"
+
 # This setting sets the location of the file which contains information about
 # most variables to get MPD back into the same general shape it was in before
 # it was brought down. This setting is disabled by default and the server
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/doc/plugins.rst 
new/mpd-0.23.4/doc/plugins.rst
--- old/mpd-0.23.3/doc/plugins.rst      2021-10-31 18:13:10.000000000 +0100
+++ new/mpd-0.23.4/doc/plugins.rst      2021-11-11 10:16:36.000000000 +0100
@@ -61,6 +61,15 @@
 
 Provides access to UPnP media servers.
 
+.. list-table::
+   :widths: 20 80
+   :header-rows: 1
+
+   * - Setting
+     - Description
+   * - **interface**
+     - Interface used to discover media servers. Decided by upnp if left 
unconfigured.
+
 Storage plugins
 ===============
 
@@ -841,6 +850,11 @@
        ("stop" or "pause") in DSD mode (native DSD or DoP).  This is a
        workaround for some DACs which emit noise when stopping DSD
        playback.
+   * - **thesycon_dsd_workaround yes|no**
+     - If enabled, enables a workaround for a bug in Thesycon USB
+       audio receivers.  On these devices, playing DSD512 or PCM
+       causes all subsequent attempts to play other DSD rates to fail,
+       which can be fixed by briefly playing PCM at 44.1 kHz.
    * - **allowed_formats F1 F2 ...**
      - Specifies a list of allowed audio formats, separated by a space. All 
items may contain asterisks as a wild card, and may be followed by "=dop" to 
enable DoP (DSD over PCM) for this particular format. The first matching format 
is used, and if none matches, MPD chooses the best fallback of this list.
        
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/doc/protocol.rst 
new/mpd-0.23.4/doc/protocol.rst
--- old/mpd-0.23.3/doc/protocol.rst     2021-10-31 18:13:10.000000000 +0100
+++ new/mpd-0.23.4/doc/protocol.rst     2021-11-11 10:16:36.000000000 +0100
@@ -1225,7 +1225,7 @@
 
 .. _command_searchaddpl:
 
-:command:`searchaddpl {NAME} {FILTER} [sort {TYPE}] [window {START:END}]`
+:command:`searchaddpl {NAME} {FILTER} [sort {TYPE}] [window {START:END}] 
[position POS]`
     Search the database for songs matching
     ``FILTER`` (see :ref:`Filters <filter_syntax>`) and add them to
     the playlist named ``NAME``.
@@ -1234,6 +1234,9 @@
 
     Parameters have the same meaning as for :ref:`search <command_search>`.
 
+    The ``position`` parameter specifies where the songs will be
+    inserted. [#since_0_23_4]_
+
 .. _command_update:
 
 :command:`update [URI]`
@@ -1655,3 +1658,4 @@
 .. [#since_0_23] Since :program:`MPD` 0.23
 .. [#since_0_23_1] Since :program:`MPD` 0.23.1
 .. [#since_0_23_3] Since :program:`MPD` 0.23.3
+.. [#since_0_23_4] Since :program:`MPD` 0.23.4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/meson.build new/mpd-0.23.4/meson.build
--- old/mpd-0.23.3/meson.build  2021-10-31 18:13:10.000000000 +0100
+++ new/mpd-0.23.4/meson.build  2021-11-11 10:16:36.000000000 +0100
@@ -1,7 +1,7 @@
 project(
   'mpd',
   ['c', 'cpp'],
-  version: '0.23.3',
+  version: '0.23.4',
   meson_version: '>= 0.56.0',
   default_options: [
     'c_std=c11',
@@ -44,7 +44,7 @@
 version_conf.set_quoted('PACKAGE', meson.project_name())
 version_conf.set_quoted('PACKAGE_NAME', meson.project_name())
 version_conf.set_quoted('VERSION', meson.project_version())
-version_conf.set_quoted('PROTOCOL_VERSION', '0.23.3')
+version_conf.set_quoted('PROTOCOL_VERSION', '0.23.4')
 configure_file(output: 'Version.h', configuration: version_conf)
 
 conf = configuration_data()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/python/build/libs.py 
new/mpd-0.23.4/python/build/libs.py
--- old/mpd-0.23.3/python/build/libs.py 2021-10-31 18:13:10.000000000 +0100
+++ new/mpd-0.23.4/python/build/libs.py 2021-11-11 10:16:36.000000000 +0100
@@ -116,8 +116,12 @@
     '892aea7a599b5d21842bebf463b5aafdad5711be7008dd84401920c6234820af',
     'lib/libopenmpt.a',
     [
-        '--disable-shared', '--enable-static'
+        '--disable-shared', '--enable-static',
+        '--disable-openmpt123',
+        '--without-mpg123', '--without-ogg', '--without-vorbis', 
'--without-vorbisfile',
+        '--without-portaudio', '--without-portaudiocpp', '--without-sndfile',
     ],
+    base='libopenmpt-0.5.12+release.autotools',
 )
 
 wildmidi = CmakeProject(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/src/CommandLine.cxx 
new/mpd-0.23.4/src/CommandLine.cxx
--- old/mpd-0.23.3/src/CommandLine.cxx  2021-10-31 18:13:10.000000000 +0100
+++ new/mpd-0.23.4/src/CommandLine.cxx  2021-11-11 10:16:36.000000000 +0100
@@ -86,6 +86,9 @@
        OPTION_KILL,
        OPTION_NO_CONFIG,
        OPTION_NO_DAEMON,
+#ifdef __linux__
+       OPTION_SYSTEMD,
+#endif
        OPTION_STDOUT,
        OPTION_STDERR,
        OPTION_VERBOSE,
@@ -98,6 +101,9 @@
        {"kill", "kill the currently running mpd session"},
        {"no-config", "don't read from config"},
        {"no-daemon", "don't detach from console"},
+#ifdef __linux__
+       {"systemd", "systemd service mode"},
+#endif
        {"stdout", nullptr}, // hidden, compatibility with old versions
        {"stderr", "print messages to stderr"},
        {"verbose", 'v', "verbose logging"},
@@ -328,7 +334,7 @@
 }
 
 void
-ParseCommandLine(int argc, char **argv, struct options &options,
+ParseCommandLine(int argc, char **argv, CommandLineOptions &options,
                 ConfigData &config)
 {
        bool use_config_file = true;
@@ -349,6 +355,13 @@
                        options.daemon = false;
                        break;
 
+#ifdef __linux__
+               case OPTION_SYSTEMD:
+                       options.daemon = false;
+                       options.systemd = true;
+                       break;
+#endif
+
                case OPTION_STDOUT:
                case OPTION_STDERR:
                        options.log_stderr = true;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/src/CommandLine.hxx 
new/mpd-0.23.4/src/CommandLine.hxx
--- old/mpd-0.23.3/src/CommandLine.hxx  2021-10-31 18:13:10.000000000 +0100
+++ new/mpd-0.23.4/src/CommandLine.hxx  2021-11-11 10:16:36.000000000 +0100
@@ -22,15 +22,20 @@
 
 struct ConfigData;
 
-struct options {
+struct CommandLineOptions {
        bool kill = false;
        bool daemon = true;
+
+#ifdef __linux__
+       bool systemd = false;
+#endif
+
        bool log_stderr = false;
        bool verbose = false;
 };
 
 void
-ParseCommandLine(int argc, char **argv, struct options &options,
+ParseCommandLine(int argc, char **argv, CommandLineOptions &options,
                 ConfigData &config);
 
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/src/Main.cxx new/mpd-0.23.4/src/Main.cxx
--- old/mpd-0.23.3/src/Main.cxx 2021-10-31 18:13:10.000000000 +0100
+++ new/mpd-0.23.4/src/Main.cxx 2021-11-11 10:16:36.000000000 +0100
@@ -142,14 +142,24 @@
 #ifdef ENABLE_DAEMON
 
 static void
-glue_daemonize_init(const struct options *options,
+glue_daemonize_init(const CommandLineOptions &options,
                    const ConfigData &config)
 {
+       auto pid_file = config.GetPath(ConfigOption::PID_FILE);
+
+#ifdef __linux__
+       if (options.systemd && pid_file != nullptr) {
+               pid_file = nullptr;
+               fprintf(stderr,
+                       "Ignoring the 'pid_file' setting in systemd mode\n");
+       }
+#endif
+
        daemonize_init(config.GetString(ConfigOption::USER),
                       config.GetString(ConfigOption::GROUP),
-                      config.GetPath(ConfigOption::PID_FILE));
+                      std::move(pid_file));
 
-       if (options->kill)
+       if (options.kill)
                daemonize_kill();
 }
 
@@ -361,7 +371,8 @@
 }
 
 static inline void
-MainConfigured(const struct options &options, const ConfigData &raw_config)
+MainConfigured(const CommandLineOptions &options,
+              const ConfigData &raw_config)
 {
 #ifdef ENABLE_DAEMON
        daemonize_close_stdin();
@@ -384,7 +395,7 @@
        const Config config(raw_config);
 
 #ifdef ENABLE_DAEMON
-       glue_daemonize_init(&options, raw_config);
+       glue_daemonize_init(options, raw_config);
 #endif
 
        TagLoadConfig(raw_config);
@@ -582,7 +593,7 @@
 static void
 AndroidMain()
 {
-       struct options options;
+       CommandLineOptions options;
        ConfigData raw_config;
 
        const auto sdcard = Environment::getExternalStorageDirectory();
@@ -642,7 +653,7 @@
 static inline void
 MainOrThrow(int argc, char *argv[])
 {
-       struct options options;
+       CommandLineOptions options;
        ConfigData raw_config;
 
        ParseCommandLine(argc, argv, options, raw_config);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/src/command/DatabaseCommands.cxx 
new/mpd-0.23.4/src/command/DatabaseCommands.cxx
--- old/mpd-0.23.3/src/command/DatabaseCommands.cxx     2021-10-31 
18:13:10.000000000 +0100
+++ new/mpd-0.23.4/src/command/DatabaseCommands.cxx     2021-11-11 
10:16:36.000000000 +0100
@@ -199,13 +199,20 @@
 {
        const char *playlist = args.shift();
 
+       const unsigned position = ParseQueuePosition(args, UINT_MAX);
+
        SongFilter filter;
        const auto selection = ParseDatabaseSelection(args, true, filter);
 
        const Database &db = client.GetDatabaseOrThrow();
 
-       search_add_to_playlist(db, client.GetStorage(),
-                              playlist, selection);
+       if (position == UINT_MAX)
+               search_add_to_playlist(db, client.GetStorage(),
+                                      playlist, selection);
+       else
+               SearchInsertIntoPlaylist(db, client.GetStorage(), selection,
+                                        playlist, position);
+
        return CommandResult::OK;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/src/command/PlaylistCommands.cxx 
new/mpd-0.23.4/src/command/PlaylistCommands.cxx
--- old/mpd-0.23.3/src/command/PlaylistCommands.cxx     2021-10-31 
18:13:10.000000000 +0100
+++ new/mpd-0.23.4/src/command/PlaylistCommands.cxx     2021-11-11 
10:16:36.000000000 +0100
@@ -231,15 +231,14 @@
                editor.Insert(position, uri);
        } else {
 #ifdef ENABLE_DATABASE
-               const auto &db = client.GetDatabaseOrThrow();
-               const auto *storage = client.GetStorage();
                const DatabaseSelection selection(uri, true, nullptr);
 
-               db.Visit(selection, [&editor, &position, storage](const auto 
&song){
-                       editor.Insert(position,
-                                     DatabaseDetachSong(storage, song));
-                       ++position;
-               });
+               if (SearchInsertIntoPlaylist(client.GetDatabaseOrThrow(),
+                                            client.GetStorage(),
+                                            selection,
+                                            editor, position) == 0)
+                       /* no song was found, don't need to save */
+                       return CommandResult::OK;
 #else
                (void)client;
                r.Error(ACK_ERROR_NO_EXIST, "No database");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/src/db/DatabasePlaylist.cxx 
new/mpd-0.23.4/src/db/DatabasePlaylist.cxx
--- old/mpd-0.23.3/src/db/DatabasePlaylist.cxx  2021-10-31 18:13:10.000000000 
+0100
+++ new/mpd-0.23.4/src/db/DatabasePlaylist.cxx  2021-11-11 10:16:36.000000000 
+0100
@@ -22,6 +22,7 @@
 #include "PlaylistFile.hxx"
 #include "Interface.hxx"
 #include "song/DetachedSong.hxx"
+#include "protocol/Ack.hxx"
 
 #include <functional>
 
@@ -41,3 +42,42 @@
        const auto f = [=](auto && arg1) { return AddSong(storage, 
playlist_path_utf8, arg1); };
        db.Visit(selection, f);
 }
+
+unsigned
+SearchInsertIntoPlaylist(const Database &db, const Storage *storage,
+                        const DatabaseSelection &selection,
+                        PlaylistFileEditor &playlist,
+                        unsigned position)
+{
+       assert(position <= playlist.size());
+
+       unsigned n = 0;
+
+       db.Visit(selection, [&playlist, &position, &n, storage](const auto 
&song){
+               playlist.Insert(position + n,
+                               DatabaseDetachSong(storage, song));
+               ++position;
+               ++n;
+       });
+
+       return n;
+}
+
+void
+SearchInsertIntoPlaylist(const Database &db, const Storage *storage,
+                        const DatabaseSelection &selection,
+                        const char *playlist_name,
+                        unsigned position)
+{
+       PlaylistFileEditor editor{
+               playlist_name,
+               PlaylistFileEditor::LoadMode::TRY,
+       };
+
+       if (position > editor.size())
+               throw ProtocolError{ACK_ERROR_ARG, "Bad position"};
+
+       if (SearchInsertIntoPlaylist(db, storage, selection,
+                                    editor, position) > 0)
+               editor.Save();
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/src/db/DatabasePlaylist.hxx 
new/mpd-0.23.4/src/db/DatabasePlaylist.hxx
--- old/mpd-0.23.3/src/db/DatabasePlaylist.hxx  2021-10-31 18:13:10.000000000 
+0100
+++ new/mpd-0.23.4/src/db/DatabasePlaylist.hxx  2021-11-11 10:16:36.000000000 
+0100
@@ -25,6 +25,7 @@
 class Database;
 class Storage;
 struct DatabaseSelection;
+class PlaylistFileEditor;
 
 gcc_nonnull(3)
 void
@@ -32,4 +33,19 @@
                       const char *playlist_path_utf8,
                       const DatabaseSelection &selection);
 
+/**
+ * @return the number of songs added
+ */
+unsigned
+SearchInsertIntoPlaylist(const Database &db, const Storage *storage,
+                        const DatabaseSelection &selection,
+                        PlaylistFileEditor &playlist,
+                        unsigned position);
+
+void
+SearchInsertIntoPlaylist(const Database &db, const Storage *storage,
+                        const DatabaseSelection &selection,
+                        const char *playlist_name,
+                        unsigned position);
+
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/mpd-0.23.3/src/db/plugins/upnp/UpnpDatabasePlugin.cxx 
new/mpd-0.23.4/src/db/plugins/upnp/UpnpDatabasePlugin.cxx
--- old/mpd-0.23.3/src/db/plugins/upnp/UpnpDatabasePlugin.cxx   2021-10-31 
18:13:10.000000000 +0100
+++ new/mpd-0.23.4/src/db/plugins/upnp/UpnpDatabasePlugin.cxx   2021-11-11 
10:16:36.000000000 +0100
@@ -39,6 +39,7 @@
 #include "util/ConstBuffer.hxx"
 #include "util/RecursiveMap.hxx"
 #include "util/SplitString.hxx"
+#include "config/Block.hxx"
 
 #include <cassert>
 #include <string>
@@ -76,10 +77,13 @@
        UpnpClient_Handle handle;
        UPnPDeviceDirectory *discovery;
 
+       const char* interface;
+
 public:
-       explicit UpnpDatabase(EventLoop &_event_loop) noexcept
+       explicit UpnpDatabase(EventLoop &_event_loop, const ConfigBlock &block) 
noexcept
                :Database(upnp_db_plugin),
-                event_loop(_event_loop) {}
+                event_loop(_event_loop),
+                interface(block.GetBlockValue("interface", nullptr)) {}
 
        static DatabasePtr Create(EventLoop &main_event_loop,
                                  EventLoop &io_event_loop,
@@ -147,15 +151,15 @@
 DatabasePtr
 UpnpDatabase::Create(EventLoop &, EventLoop &io_event_loop,
                     [[maybe_unused]] DatabaseListener &listener,
-                    const ConfigBlock &) noexcept
+                    const ConfigBlock &block) noexcept
 {
-       return std::make_unique<UpnpDatabase>(io_event_loop);
+       return std::make_unique<UpnpDatabase>(io_event_loop, block);;
 }
 
 void
 UpnpDatabase::Open()
 {
-       handle = UpnpClientGlobalInit();
+       handle = UpnpClientGlobalInit(interface);
 
        discovery = new UPnPDeviceDirectory(event_loop, handle);
        try {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/mpd-0.23.3/src/decoder/plugins/FfmpegDecoderPlugin.cxx 
new/mpd-0.23.4/src/decoder/plugins/FfmpegDecoderPlugin.cxx
--- old/mpd-0.23.3/src/decoder/plugins/FfmpegDecoderPlugin.cxx  2021-10-31 
18:13:10.000000000 +0100
+++ new/mpd-0.23.4/src/decoder/plugins/FfmpegDecoderPlugin.cxx  2021-11-11 
10:16:36.000000000 +0100
@@ -502,7 +502,7 @@
                FmtDebug(ffmpeg_domain, "codec '{}'",
                         codec_descriptor->name);
 
-       AVCodec *codec = avcodec_find_decoder(codec_params.codec_id);
+       const AVCodec *codec = avcodec_find_decoder(codec_params.codec_id);
 
        if (!codec) {
                LogError(ffmpeg_domain, "Unsupported audio codec");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/src/event/Loop.cxx 
new/mpd-0.23.4/src/event/Loop.cxx
--- old/mpd-0.23.3/src/event/Loop.cxx   2021-10-31 18:13:10.000000000 +0100
+++ new/mpd-0.23.4/src/event/Loop.cxx   2021-11-11 10:16:36.000000000 +0100
@@ -52,6 +52,13 @@
 
 EventLoop::~EventLoop() noexcept
 {
+#if defined(HAVE_URING) && !defined(NDEBUG)
+       /* if Run() was never called (maybe because startup failed and
+          an exception is pending), we need to destruct the
+          Uring::Manager here or else the assertions below fail */
+       uring.reset();
+#endif
+
        assert(defer.empty());
        assert(idle.empty());
 #ifdef HAVE_THREADED_EVENT_LOOP
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/src/input/plugins/AlsaInputPlugin.cxx 
new/mpd-0.23.4/src/input/plugins/AlsaInputPlugin.cxx
--- old/mpd-0.23.3/src/input/plugins/AlsaInputPlugin.cxx        2021-10-31 
18:13:10.000000000 +0100
+++ new/mpd-0.23.4/src/input/plugins/AlsaInputPlugin.cxx        2021-11-11 
10:16:36.000000000 +0100
@@ -26,6 +26,7 @@
 
 #include "AlsaInputPlugin.hxx"
 #include "lib/alsa/NonBlock.hxx"
+#include "lib/alsa/Error.hxx"
 #include "lib/alsa/Format.hxx"
 #include "../InputPlugin.hxx"
 #include "../AsyncInputStream.hxx"
@@ -332,28 +333,23 @@
        snd_pcm_hw_params_alloca(&hw_params);
 
        if ((err = snd_pcm_hw_params_any(capture_handle, hw_params)) < 0)
-               throw FormatRuntimeError("Cannot initialize hardware parameter 
structure (%s)",
-                                        snd_strerror(err));
+               throw Alsa::MakeError(err, "snd_pcm_hw_params_any() failed");
 
        if ((err = snd_pcm_hw_params_set_access(capture_handle, hw_params,
                                               SND_PCM_ACCESS_RW_INTERLEAVED)) 
< 0)
-               throw FormatRuntimeError("Cannot set access type (%s)",
-                                        snd_strerror(err));
+               throw Alsa::MakeError(err, "snd_pcm_hw_params_set_access() 
failed");
 
        if ((err = snd_pcm_hw_params_set_format(capture_handle, hw_params,
                                        ToAlsaPcmFormat(audio_format.format))) 
< 0)
-               throw FormatRuntimeError("Cannot set sample format (%s)",
-                                        snd_strerror(err));
+               throw Alsa::MakeError(err, "Cannot set sample format");
 
        if ((err = snd_pcm_hw_params_set_channels(capture_handle,
                                            hw_params, audio_format.channels)) 
< 0)
-               throw FormatRuntimeError("Cannot set channels (%s)",
-                                        snd_strerror(err));
+               throw Alsa::MakeError(err, "Cannot set channels");
 
        if ((err = snd_pcm_hw_params_set_rate(capture_handle,
                                      hw_params, audio_format.sample_rate, 0)) 
< 0)
-               throw FormatRuntimeError("Cannot set sample rate (%s)",
-                                        snd_strerror(err));
+               throw Alsa::MakeError(err, "Cannot set sample rate");
 
        snd_pcm_uframes_t buffer_size_min, buffer_size_max;
        snd_pcm_hw_params_get_buffer_size_min(hw_params, &buffer_size_min);
@@ -388,26 +384,22 @@
                int direction = -1;
                if ((err = 
snd_pcm_hw_params_set_period_size_near(capture_handle,
                                             hw_params, &period_size, 
&direction)) < 0)
-                       throw FormatRuntimeError("Cannot set period size (%s)",
-                                                snd_strerror(err));
+                       throw Alsa::MakeError(err, "Cannot set period size");
        }
 
        if ((err = snd_pcm_hw_params(capture_handle, hw_params)) < 0)
-               throw FormatRuntimeError("Cannot set parameters (%s)",
-                                        snd_strerror(err));
+               throw Alsa::MakeError(err, "snd_pcm_hw_params() failed");
 
        snd_pcm_uframes_t alsa_buffer_size;
        err = snd_pcm_hw_params_get_buffer_size(hw_params, &alsa_buffer_size);
        if (err < 0)
-               throw FormatRuntimeError("snd_pcm_hw_params_get_buffer_size() 
failed: %s",
-                                        snd_strerror(-err));
+               throw Alsa::MakeError(err, "snd_pcm_hw_params_get_buffer_size() 
failed");
 
        snd_pcm_uframes_t alsa_period_size;
        err = snd_pcm_hw_params_get_period_size(hw_params, &alsa_period_size,
                                                nullptr);
        if (err < 0)
-               throw FormatRuntimeError("snd_pcm_hw_params_get_period_size() 
failed: %s",
-                                        snd_strerror(-err));
+               throw Alsa::MakeError(err, "snd_pcm_hw_params_get_period_size() 
failed");
 
        FmtDebug(alsa_input_domain, "buffer_size={} period_size={}",
                 alsa_buffer_size, alsa_period_size);
@@ -418,8 +410,7 @@
        snd_pcm_sw_params_current(capture_handle, sw_params);
 
        if ((err = snd_pcm_sw_params(capture_handle, sw_params)) < 0)
-               throw FormatRuntimeError("unable to install sw params (%s)",
-                                        snd_strerror(err));
+               throw Alsa::MakeError(err, "snd_pcm_sw_params() failed");
 }
 
 inline void
@@ -430,8 +421,9 @@
        if ((err = snd_pcm_open(&capture_handle, spec.GetDeviceName(),
                                SND_PCM_STREAM_CAPTURE,
                                SND_PCM_NONBLOCK | global_config.mode)) < 0)
-               throw FormatRuntimeError("Failed to open device: %s (%s)",
-                                        spec.GetDeviceName(), 
snd_strerror(err));
+               throw Alsa::MakeError(err,
+                                     fmt::format("Failed to open device {}",
+                                                 
spec.GetDeviceName()).c_str());
 
        try {
                ConfigureCapture(spec.GetAudioFormat());
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/src/lib/alsa/Error.cxx 
new/mpd-0.23.4/src/lib/alsa/Error.cxx
--- old/mpd-0.23.3/src/lib/alsa/Error.cxx       1970-01-01 01:00:00.000000000 
+0100
+++ new/mpd-0.23.4/src/lib/alsa/Error.cxx       2021-11-11 10:16:36.000000000 
+0100
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021 Max Kellermann <[email protected]>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "Error.hxx"
+
+#include <alsa/error.h>
+
+namespace Alsa {
+
+ErrorCategory error_category;
+
+std::string
+ErrorCategory::message(int condition) const
+{
+       return snd_strerror(condition);
+}
+
+} // namespace Avahi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/src/lib/alsa/Error.hxx 
new/mpd-0.23.4/src/lib/alsa/Error.hxx
--- old/mpd-0.23.3/src/lib/alsa/Error.hxx       1970-01-01 01:00:00.000000000 
+0100
+++ new/mpd-0.23.4/src/lib/alsa/Error.hxx       2021-11-11 10:16:36.000000000 
+0100
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2021 Max Kellermann <[email protected]>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
+ * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <system_error>
+
+namespace Alsa {
+
+class ErrorCategory final : public std::error_category {
+public:
+       const char *name() const noexcept override {
+               return "libasound";
+       }
+
+       std::string message(int condition) const override;
+};
+
+extern ErrorCategory error_category;
+
+inline std::system_error
+MakeError(int error, const char *msg) noexcept
+{
+       return std::system_error(error, error_category, msg);
+}
+
+} // namespace Avahi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/src/lib/alsa/HwSetup.cxx 
new/mpd-0.23.4/src/lib/alsa/HwSetup.cxx
--- old/mpd-0.23.3/src/lib/alsa/HwSetup.cxx     2021-10-31 18:13:10.000000000 
+0100
+++ new/mpd-0.23.4/src/lib/alsa/HwSetup.cxx     2021-11-11 10:16:36.000000000 
+0100
@@ -18,7 +18,9 @@
  */
 
 #include "HwSetup.hxx"
+#include "Error.hxx"
 #include "Format.hxx"
+#include "lib/fmt/AudioFormatFormatter.hxx"
 #include "util/ByteOrder.hxx"
 #include "util/Domain.hxx"
 #include "util/RuntimeError.hxx"
@@ -185,29 +187,27 @@
        /* configure HW params */
        err = snd_pcm_hw_params_any(pcm, hwparams);
        if (err < 0)
-               throw FormatRuntimeError("snd_pcm_hw_params_any() failed: %s",
-                                        snd_strerror(-err));
+               throw Alsa::MakeError(err, "snd_pcm_hw_params_any() failed");
 
        err = snd_pcm_hw_params_set_access(pcm, hwparams,
                                           SND_PCM_ACCESS_RW_INTERLEAVED);
        if (err < 0)
-               throw FormatRuntimeError("snd_pcm_hw_params_set_access() 
failed: %s",
-                                        snd_strerror(-err));
+               throw Alsa::MakeError(err, "snd_pcm_hw_params_set_access() 
failed");
 
        err = SetupSampleFormat(pcm, hwparams,
                                audio_format.format, params);
        if (err < 0)
-               throw FormatRuntimeError("Failed to configure format %s: %s",
-                                        
sample_format_to_string(audio_format.format),
-                                        snd_strerror(-err));
+               throw Alsa::MakeError(err,
+                                     fmt::format("Failed to configure format 
{}",
+                                                 audio_format.format).c_str());
 
        unsigned int channels = audio_format.channels;
        err = snd_pcm_hw_params_set_channels_near(pcm, hwparams,
                                                  &channels);
        if (err < 0)
-               throw FormatRuntimeError("Failed to configure %i channels: %s",
-                                        (int)audio_format.channels,
-                                        snd_strerror(-err));
+               throw Alsa::MakeError(err,
+                                     fmt::format("Failed to configure {} 
channels",
+                                                 
audio_format.channels).c_str());
 
        audio_format.channels = (int8_t)channels;
 
@@ -218,9 +218,9 @@
        err = snd_pcm_hw_params_set_rate_near(pcm, hwparams,
                                              &output_sample_rate, nullptr);
        if (err < 0)
-               throw FormatRuntimeError("Failed to configure sample rate %u 
Hz: %s",
-                                        requested_sample_rate,
-                                        snd_strerror(-err));
+               throw Alsa::MakeError(err,
+                                     fmt::format("Failed to configure sample 
rate {} Hz",
+                                                 
requested_sample_rate).c_str());
 
        if (output_sample_rate == 0)
                throw FormatRuntimeError("Failed to configure sample rate %u 
Hz",
@@ -253,8 +253,7 @@
                err = snd_pcm_hw_params_set_buffer_time_near(pcm, hwparams,
                                                             &buffer_time, 
nullptr);
                if (err < 0)
-                       throw 
FormatRuntimeError("snd_pcm_hw_params_set_buffer_time_near() failed: %s",
-                                                snd_strerror(-err));
+                       throw Alsa::MakeError(err, 
"snd_pcm_hw_params_set_buffer_time_near() failed");
        } else {
                err = snd_pcm_hw_params_get_buffer_time(hwparams, &buffer_time,
                                                        nullptr);
@@ -275,32 +274,27 @@
                err = snd_pcm_hw_params_set_period_time_near(pcm, hwparams,
                                                             &period_time, 
nullptr);
                if (err < 0)
-                       throw 
FormatRuntimeError("snd_pcm_hw_params_set_period_time_near() failed: %s",
-                                                snd_strerror(-err));
+                       throw Alsa::MakeError(err, 
"snd_pcm_hw_params_set_period_time_near() failed");
        }
 
        err = snd_pcm_hw_params(pcm, hwparams);
        if (err < 0)
-               throw FormatRuntimeError("snd_pcm_hw_params() failed: %s",
-                                        snd_strerror(-err));
+               throw Alsa::MakeError(err, "snd_pcm_hw_params() failed");
 
        HwResult result;
 
        err = snd_pcm_hw_params_get_format(hwparams, &result.format);
        if (err < 0)
-               throw FormatRuntimeError("snd_pcm_hw_params_get_format() 
failed: %s",
-                                        snd_strerror(-err));
+               throw Alsa::MakeError(err, "snd_pcm_hw_params_get_format() 
failed");
 
        err = snd_pcm_hw_params_get_buffer_size(hwparams, &result.buffer_size);
        if (err < 0)
-               throw FormatRuntimeError("snd_pcm_hw_params_get_buffer_size() 
failed: %s",
-                                        snd_strerror(-err));
+               throw Alsa::MakeError(err, "snd_pcm_hw_params_get_buffer_size() 
failed");
 
        err = snd_pcm_hw_params_get_period_size(hwparams, &result.period_size,
                                                nullptr);
        if (err < 0)
-               throw FormatRuntimeError("snd_pcm_hw_params_get_period_size() 
failed: %s",
-                                        snd_strerror(-err));
+               throw Alsa::MakeError(err, "snd_pcm_hw_params_get_period_size() 
failed");
 
        return result;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/src/lib/alsa/NonBlock.cxx 
new/mpd-0.23.4/src/lib/alsa/NonBlock.cxx
--- old/mpd-0.23.3/src/lib/alsa/NonBlock.cxx    2021-10-31 18:13:10.000000000 
+0100
+++ new/mpd-0.23.4/src/lib/alsa/NonBlock.cxx    2021-11-11 10:16:36.000000000 
+0100
@@ -18,6 +18,7 @@
  */
 
 #include "NonBlock.hxx"
+#include "Error.hxx"
 #include "event/MultiSocketMonitor.hxx"
 #include "util/RuntimeError.hxx"
 
@@ -29,8 +30,7 @@
                if (count == 0)
                        throw 
std::runtime_error("snd_pcm_poll_descriptors_count() failed");
                else
-                       throw 
FormatRuntimeError("snd_pcm_poll_descriptors_count() failed: %s",
-                                                snd_strerror(-count));
+                       throw Alsa::MakeError(count, 
"snd_pcm_poll_descriptors_count() failed");
        }
 
        struct pollfd *pfds = pfd_buffer.Get(count);
@@ -40,8 +40,7 @@
                if (count == 0)
                        throw std::runtime_error("snd_pcm_poll_descriptors() 
failed");
                else
-                       throw FormatRuntimeError("snd_pcm_poll_descriptors() 
failed: %s",
-                                                snd_strerror(-count));
+                       throw Alsa::MakeError(count, 
"snd_pcm_poll_descriptors() failed");
        }
 
        m.ReplaceSocketList(pfds, count);
@@ -71,8 +70,7 @@
        unsigned short dummy;
        int err = snd_pcm_poll_descriptors_revents(pcm, pfds, i - pfds, &dummy);
        if (err < 0)
-               throw FormatRuntimeError("snd_pcm_poll_descriptors_revents() 
failed: %s",
-                                        snd_strerror(-err));
+               throw Alsa::MakeError(err, "snd_pcm_poll_descriptors_revents() 
failed");
 }
 
 Event::Duration
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/src/lib/alsa/meson.build 
new/mpd-0.23.4/src/lib/alsa/meson.build
--- old/mpd-0.23.3/src/lib/alsa/meson.build     2021-10-31 18:13:10.000000000 
+0100
+++ new/mpd-0.23.4/src/lib/alsa/meson.build     2021-11-11 10:16:36.000000000 
+0100
@@ -14,6 +14,7 @@
 alsa = static_library(
   'alsa',
   'Version.cxx',
+  'Error.cxx',
   'AllowedFormat.cxx',
   'HwSetup.cxx',
   'NonBlock.cxx',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/src/lib/ffmpeg/Codec.hxx 
new/mpd-0.23.4/src/lib/ffmpeg/Codec.hxx
--- old/mpd-0.23.3/src/lib/ffmpeg/Codec.hxx     2021-10-31 18:13:10.000000000 
+0100
+++ new/mpd-0.23.4/src/lib/ffmpeg/Codec.hxx     2021-11-11 10:16:36.000000000 
+0100
@@ -36,7 +36,7 @@
 public:
        CodecContext() = default;
 
-       explicit CodecContext(AVCodec &codec)
+       explicit CodecContext(const AVCodec &codec)
                :codec_context(avcodec_alloc_context3(&codec))
        {
                if (codec_context == nullptr)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/src/lib/fmt/AudioFormatFormatter.hxx 
new/mpd-0.23.4/src/lib/fmt/AudioFormatFormatter.hxx
--- old/mpd-0.23.3/src/lib/fmt/AudioFormatFormatter.hxx 2021-10-31 
18:13:10.000000000 +0100
+++ new/mpd-0.23.4/src/lib/fmt/AudioFormatFormatter.hxx 2021-11-11 
10:16:36.000000000 +0100
@@ -36,6 +36,16 @@
 #include <fmt/format.h>
 
 template<>
+struct fmt::formatter<SampleFormat> : formatter<string_view>
+{
+       template<typename FormatContext>
+       auto format(const SampleFormat format, FormatContext &ctx) {
+               return 
formatter<string_view>::format(sample_format_to_string(format),
+                                                     ctx);
+       }
+};
+
+template<>
 struct fmt::formatter<AudioFormat> : formatter<string_view>
 {
        template<typename FormatContext>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/src/lib/upnp/ClientInit.cxx 
new/mpd-0.23.4/src/lib/upnp/ClientInit.cxx
--- old/mpd-0.23.3/src/lib/upnp/ClientInit.cxx  2021-10-31 18:13:10.000000000 
+0100
+++ new/mpd-0.23.4/src/lib/upnp/ClientInit.cxx  2021-11-11 10:16:36.000000000 
+0100
@@ -57,9 +57,9 @@
 }
 
 UpnpClient_Handle
-UpnpClientGlobalInit()
+UpnpClientGlobalInit(const char* iface)
 {
-       UpnpGlobalInit();
+       UpnpGlobalInit(iface);
 
        try {
                const std::lock_guard<Mutex> protect(upnp_client_init_mutex);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/src/lib/upnp/ClientInit.hxx 
new/mpd-0.23.4/src/lib/upnp/ClientInit.hxx
--- old/mpd-0.23.3/src/lib/upnp/ClientInit.hxx  2021-10-31 18:13:10.000000000 
+0100
+++ new/mpd-0.23.4/src/lib/upnp/ClientInit.hxx  2021-11-11 10:16:36.000000000 
+0100
@@ -23,7 +23,7 @@
 #include "Compat.hxx"
 
 UpnpClient_Handle
-UpnpClientGlobalInit();
+UpnpClientGlobalInit(const char* iface);
 
 void
 UpnpClientGlobalFinish() noexcept;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/src/lib/upnp/Init.cxx 
new/mpd-0.23.4/src/lib/upnp/Init.cxx
--- old/mpd-0.23.3/src/lib/upnp/Init.cxx        2021-10-31 18:13:10.000000000 
+0100
+++ new/mpd-0.23.4/src/lib/upnp/Init.cxx        2021-11-11 10:16:36.000000000 
+0100
@@ -33,12 +33,13 @@
 static unsigned upnp_ref;
 
 static void
-DoInit()
+DoInit(const char* iface)
 {
+
 #ifdef UPNP_ENABLE_IPV6
-       auto code = UpnpInit2(nullptr, 0);
+       auto code = UpnpInit2(iface, 0);
 #else
-       auto code = UpnpInit(nullptr, 0);
+       auto code = UpnpInit(iface, 0);
 #endif
        if (code != UPNP_E_SUCCESS)
                throw FormatRuntimeError("UpnpInit() failed: %s",
@@ -53,12 +54,12 @@
 }
 
 void
-UpnpGlobalInit()
+UpnpGlobalInit(const char* iface)
 {
        const std::lock_guard<Mutex> protect(upnp_init_mutex);
 
        if (upnp_ref == 0)
-               DoInit();
+               DoInit(iface);
 
        ++upnp_ref;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/src/lib/upnp/Init.hxx 
new/mpd-0.23.4/src/lib/upnp/Init.hxx
--- old/mpd-0.23.3/src/lib/upnp/Init.hxx        2021-10-31 18:13:10.000000000 
+0100
+++ new/mpd-0.23.4/src/lib/upnp/Init.hxx        2021-11-11 10:16:36.000000000 
+0100
@@ -21,7 +21,7 @@
 #define MPD_UPNP_INIT_HXX
 
 void
-UpnpGlobalInit();
+UpnpGlobalInit(const char* iface);
 
 void
 UpnpGlobalFinish() noexcept;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/src/mixer/plugins/AlsaMixerPlugin.cxx 
new/mpd-0.23.4/src/mixer/plugins/AlsaMixerPlugin.cxx
--- old/mpd-0.23.3/src/mixer/plugins/AlsaMixerPlugin.cxx        2021-10-31 
18:13:10.000000000 +0100
+++ new/mpd-0.23.4/src/mixer/plugins/AlsaMixerPlugin.cxx        2021-11-11 
10:16:36.000000000 +0100
@@ -18,6 +18,7 @@
  */
 
 #include "lib/alsa/NonBlock.hxx"
+#include "lib/alsa/Error.hxx"
 #include "mixer/MixerInternal.hxx"
 #include "mixer/Listener.hxx"
 #include "output/OutputAPI.hxx"
@@ -264,16 +265,15 @@
        int err;
 
        if ((err = snd_mixer_attach(handle, device)) < 0)
-               throw FormatRuntimeError("failed to attach to %s: %s",
-                                        device, snd_strerror(err));
+               throw Alsa::MakeError(err,
+                                     fmt::format("failed to attach to {}",
+                                                 device).c_str());
 
        if ((err = snd_mixer_selem_register(handle, nullptr, nullptr)) < 0)
-               throw FormatRuntimeError("snd_mixer_selem_register() failed: 
%s",
-                                        snd_strerror(err));
+               throw Alsa::MakeError(err, "snd_mixer_selem_register() failed");
 
        if ((err = snd_mixer_load(handle)) < 0)
-               throw FormatRuntimeError("snd_mixer_load() failed: %s\n",
-                                        snd_strerror(err));
+               throw Alsa::MakeError(err, "snd_mixer_load() failed");
 
        elem = alsa_mixer_lookup_elem(handle, control, index);
        if (elem == nullptr)
@@ -294,8 +294,7 @@
 
        err = snd_mixer_open(&handle, 0);
        if (err < 0)
-               throw FormatRuntimeError("snd_mixer_open() failed: %s",
-                                        snd_strerror(err));
+               throw Alsa::MakeError(err, "snd_mixer_open() failed");
 
        try {
                Setup();
@@ -325,8 +324,7 @@
 
        err = snd_mixer_handle_events(handle);
        if (err < 0)
-               throw FormatRuntimeError("snd_mixer_handle_events() failed: %s",
-                                        snd_strerror(err));
+               throw Alsa::MakeError(err, "snd_mixer_handle_events() failed");
 
        int volume = GetPercentVolume();
        if (resulting_volume >= 0 && volume == resulting_volume)
@@ -343,8 +341,7 @@
 
        int err = set_normalized_playback_volume(elem, 0.01*volume, 1);
        if (err < 0)
-               throw FormatRuntimeError("failed to set ALSA volume: %s",
-                                        snd_strerror(err));
+               throw Alsa::MakeError(err, "failed to set ALSA volume");
 
        desired_volume = volume;
        resulting_volume = GetPercentVolume();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/mpd-0.23.3/src/neighbor/plugins/UpnpNeighborPlugin.cxx 
new/mpd-0.23.4/src/neighbor/plugins/UpnpNeighborPlugin.cxx
--- old/mpd-0.23.3/src/neighbor/plugins/UpnpNeighborPlugin.cxx  2021-10-31 
18:13:10.000000000 +0100
+++ new/mpd-0.23.4/src/neighbor/plugins/UpnpNeighborPlugin.cxx  2021-11-11 
10:16:36.000000000 +0100
@@ -74,7 +74,7 @@
 void
 UpnpNeighborExplorer::Open()
 {
-       auto handle = UpnpClientGlobalInit();
+       auto handle = UpnpClientGlobalInit(nullptr);
 
        discovery = new UPnPDeviceDirectory(event_loop, handle, this);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/src/output/plugins/AlsaOutputPlugin.cxx 
new/mpd-0.23.4/src/output/plugins/AlsaOutputPlugin.cxx
--- old/mpd-0.23.3/src/output/plugins/AlsaOutputPlugin.cxx      2021-10-31 
18:13:10.000000000 +0100
+++ new/mpd-0.23.4/src/output/plugins/AlsaOutputPlugin.cxx      2021-11-11 
10:16:36.000000000 +0100
@@ -20,6 +20,7 @@
 #include "config.h"
 #include "AlsaOutputPlugin.hxx"
 #include "lib/alsa/AllowedFormat.hxx"
+#include "lib/alsa/Error.hxx"
 #include "lib/alsa/HwSetup.hxx"
 #include "lib/alsa/NonBlock.hxx"
 #include "lib/alsa/PeriodBuffer.hxx"
@@ -42,6 +43,10 @@
 #include "event/Call.hxx"
 #include "Log.hxx"
 
+#ifdef ENABLE_DSD
+#include "util/AllocatedArray.hxx"
+#endif
+
 #include <alsa/asoundlib.h>
 
 #include <boost/lockfree/spsc_queue.hpp>
@@ -101,6 +106,16 @@
         * Are we currently draining with #stop_dsd_silence?
         */
        bool in_stop_dsd_silence;
+
+       /**
+        * Enable the DSD sync workaround for Thesycon USB audio
+        * receivers?  On this device, playing DSD512 or PCM causes
+        * all subsequent attempts to play other DSD rates to fail,
+        * which can be fixed by briefly playing PCM at 44.1 kHz.
+        */
+       const bool thesycon_dsd_workaround;
+
+       bool need_thesycon_dsd_workaround = thesycon_dsd_workaround;
 #endif
 
        /** libasound's buffer_time setting (in microseconds) */
@@ -432,6 +447,8 @@
                     /* legacy name from MPD 0.18 and older: */
                     block.GetBlockValue("dsd_usb", false)),
         stop_dsd_silence(block.GetBlockValue("stop_dsd_silence", false)),
+        thesycon_dsd_workaround(block.GetBlockValue("thesycon_dsd_workaround",
+                                                    false)),
 #endif
         buffer_time(block.GetPositiveValue("buffer_time",
                                            MPD_ALSA_BUFFER_TIME_US)),
@@ -519,24 +536,20 @@
 
        int err = snd_pcm_sw_params_current(pcm, swparams);
        if (err < 0)
-               throw FormatRuntimeError("snd_pcm_sw_params_current() failed: 
%s",
-                                        snd_strerror(-err));
+               throw Alsa::MakeError(err, "snd_pcm_sw_params_current() 
failed");
 
        err = snd_pcm_sw_params_set_start_threshold(pcm, swparams,
                                                    start_threshold);
        if (err < 0)
-               throw 
FormatRuntimeError("snd_pcm_sw_params_set_start_threshold() failed: %s",
-                                        snd_strerror(-err));
+               throw Alsa::MakeError(err, 
"snd_pcm_sw_params_set_start_threshold() failed");
 
        err = snd_pcm_sw_params_set_avail_min(pcm, swparams, avail_min);
        if (err < 0)
-               throw FormatRuntimeError("snd_pcm_sw_params_set_avail_min() 
failed: %s",
-                                        snd_strerror(-err));
+               throw Alsa::MakeError(err, "snd_pcm_sw_params_set_avail_min() 
failed");
 
        err = snd_pcm_sw_params(pcm, swparams);
        if (err < 0)
-               throw FormatRuntimeError("snd_pcm_sw_params() failed: %s",
-                                        snd_strerror(-err));
+               throw Alsa::MakeError(err, "snd_pcm_sw_params() failed");
 }
 
 inline void
@@ -678,6 +691,97 @@
        return haystack.front();
 }
 
+#ifdef ENABLE_DSD
+
+static void
+Play_44_1_Silence(snd_pcm_t *pcm)
+{
+       snd_pcm_hw_params_t *hw;
+       snd_pcm_hw_params_alloca(&hw);
+
+       int err;
+
+       err = snd_pcm_hw_params_any(pcm, hw);
+       if (err < 0)
+               throw Alsa::MakeError(err, "snd_pcm_hw_params_any() failed");
+
+       err = snd_pcm_hw_params_set_access(pcm, hw,
+                                          SND_PCM_ACCESS_RW_INTERLEAVED);
+       if (err < 0)
+               throw Alsa::MakeError(err, "snd_pcm_hw_params_set_access() 
failed");
+
+       err = snd_pcm_hw_params_set_format(pcm, hw, SND_PCM_FORMAT_S16);
+       if (err < 0)
+               throw Alsa::MakeError(err, "snd_pcm_hw_params_set_format() 
failed");
+
+       unsigned channels = 1;
+       err = snd_pcm_hw_params_set_channels_near(pcm, hw, &channels);
+       if (err < 0)
+               throw Alsa::MakeError(err, 
"snd_pcm_hw_params_set_channels_near() failed");
+
+       constexpr snd_pcm_uframes_t rate = 44100;
+       err = snd_pcm_hw_params_set_rate(pcm, hw, rate, 0);
+       if (err < 0)
+               throw Alsa::MakeError(err, "snd_pcm_hw_params_set_rate() 
failed");
+
+       snd_pcm_uframes_t buffer_size = 1;
+       err = snd_pcm_hw_params_set_buffer_size_near(pcm, hw, &buffer_size);
+       if (err < 0)
+               throw Alsa::MakeError(err, 
"snd_pcm_hw_params_set_buffer_size_near() failed");
+
+       snd_pcm_uframes_t period_size = 1;
+       int dir = 0;
+       err = snd_pcm_hw_params_set_period_size_near(pcm, hw, &period_size,
+                                                    &dir);
+       if (err < 0)
+               throw Alsa::MakeError(err, 
"snd_pcm_hw_params_set_period_size_near() failed");
+
+       err = snd_pcm_hw_params(pcm, hw);
+       if (err < 0)
+               throw Alsa::MakeError(err, "snd_pcm_hw_params() failed");
+
+       snd_pcm_sw_params_t *sw;
+       snd_pcm_sw_params_alloca(&sw);
+
+       err = snd_pcm_sw_params_current(pcm, sw);
+       if (err < 0)
+               throw Alsa::MakeError(err, "snd_pcm_sw_params_current() 
failed");
+
+       err = snd_pcm_sw_params_set_start_threshold(pcm, sw, period_size);
+       if (err < 0)
+               throw Alsa::MakeError(err, 
"snd_pcm_sw_params_set_start_threshold() failed");
+
+       err = snd_pcm_sw_params(pcm, sw);
+       if (err < 0)
+               throw Alsa::MakeError(err, "snd_pcm_sw_params() failed");
+
+       err = snd_pcm_prepare(pcm);
+       if (err < 0)
+               throw Alsa::MakeError(err, "snd_pcm_prepare() failed");
+
+       AllocatedArray<int16_t> buffer{channels * period_size};
+       std::fill(buffer.begin(), buffer.end(), 0);
+
+       /* play at least 250ms of silence */
+       for (snd_pcm_uframes_t remaining_frames = rate / 4;;) {
+               auto n = snd_pcm_writei(pcm, buffer.data(),
+                                       period_size);
+               if (n < 0)
+                       throw Alsa::MakeError(err, "snd_pcm_writei() failed");
+
+               if (snd_pcm_uframes_t(n) >= remaining_frames)
+                       break;
+
+               remaining_frames -= snd_pcm_uframes_t(n);
+       }
+
+       err = snd_pcm_drain(pcm);
+       if (err < 0)
+               throw Alsa::MakeError(err, "snd_pcm_drain() failed");
+}
+
+#endif
+
 void
 AlsaOutput::Open(AudioFormat &audio_format)
 {
@@ -704,13 +808,30 @@
        int err = snd_pcm_open(&pcm, GetDevice(),
                               SND_PCM_STREAM_PLAYBACK, mode);
        if (err < 0)
-               throw FormatRuntimeError("Failed to open ALSA device \"%s\": 
%s",
-                                        GetDevice(), snd_strerror(err));
+               throw Alsa::MakeError(err,
+                                     fmt::format("Failed to open ALSA device 
\"{}\"",
+                                                 GetDevice()).c_str());
 
        FmtDebug(alsa_output_domain, "opened {} type={}",
                 snd_pcm_name(pcm),
                 snd_pcm_type_name(snd_pcm_type(pcm)));
 
+#ifdef ENABLE_DSD
+       if (need_thesycon_dsd_workaround &&
+           audio_format.format == SampleFormat::DSD &&
+           audio_format.sample_rate <= 256 * 44100 / 8) {
+               LogDebug(alsa_output_domain, "Playing some 44.1 kHz silence");
+
+               try {
+                       Play_44_1_Silence(pcm);
+               } catch (...) {
+                       LogError(std::current_exception());
+               }
+
+               need_thesycon_dsd_workaround = false;
+       }
+#endif
+
        PcmExport::Params params;
        params.alsa_channel_order = true;
 
@@ -735,6 +856,11 @@
        use_dsd = audio_format.format == SampleFormat::DSD;
        in_stop_dsd_silence = false;
 
+       if (thesycon_dsd_workaround &&
+           (!use_dsd ||
+            audio_format.sample_rate > 256 * 44100 / 8))
+               need_thesycon_dsd_workaround = true;
+
        if (params.dsd_mode == PcmExport::DsdMode::DOP)
                LogDebug(alsa_output_domain, "DoP (DSD over PCM) enabled");
 #endif
@@ -897,8 +1023,8 @@
                                if (frames_written == -EAGAIN)
                                        return false;
 
-                               throw FormatRuntimeError("snd_pcm_writei() 
failed: %s",
-                                                        
snd_strerror(-frames_written));
+                               throw Alsa::MakeError(frames_written,
+                                                     "snd_pcm_writei() 
failed");
                        }
 
                        /* need to call CopyRingToPeriodBuffer() and
@@ -947,8 +1073,7 @@
        else if (result == -EAGAIN)
                return false;
        else
-               throw FormatRuntimeError("snd_pcm_drain() failed: %s",
-                                        snd_strerror(-result));
+               throw Alsa::MakeError(result, "snd_pcm_drain() failed");
 }
 
 void
@@ -1147,8 +1272,7 @@
 
                int err = snd_pcm_prepare(pcm);
                if (err < 0)
-                       throw FormatRuntimeError("snd_pcm_prepare() failed: %s",
-                                                snd_strerror(-err));
+                       throw Alsa::MakeError(err, "snd_pcm_prepare() failed");
        }
 
        {
@@ -1236,8 +1360,8 @@
                        return;
 
                if (Recover(frames_written) < 0)
-                       throw FormatRuntimeError("snd_pcm_writei() failed: %s",
-                                                snd_strerror(-frames_written));
+                       throw Alsa::MakeError(frames_written,
+                                             "snd_pcm_writei() failed");
 
                /* recovered; try again in the next DispatchSockets()
                   call */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/mpd-0.23.3/src/output/plugins/PipeWireOutputPlugin.cxx 
new/mpd-0.23.4/src/output/plugins/PipeWireOutputPlugin.cxx
--- old/mpd-0.23.3/src/output/plugins/PipeWireOutputPlugin.cxx  2021-10-31 
18:13:10.000000000 +0100
+++ new/mpd-0.23.4/src/output/plugins/PipeWireOutputPlugin.cxx  2021-11-11 
10:16:36.000000000 +0100
@@ -55,6 +55,7 @@
 #include <boost/lockfree/spsc_queue.hpp>
 
 #include <algorithm>
+#include <array>
 #include <stdexcept>
 #include <string>
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/systemd/system/mpd.service.in 
new/mpd-0.23.4/systemd/system/mpd.service.in
--- old/mpd-0.23.3/systemd/system/mpd.service.in        2021-10-31 
18:13:10.000000000 +0100
+++ new/mpd-0.23.4/systemd/system/mpd.service.in        2021-11-11 
10:16:36.000000000 +0100
@@ -5,11 +5,7 @@
 
 [Service]
 Type=notify
-ExecStart=@prefix@/bin/mpd --no-daemon
-
-# Create /run/mpd (if MPD is launched without the socket unit and is
-# configured to bind listener sockets there).
-RuntimeDirectory=mpd
+ExecStart=@prefix@/bin/mpd --systemd
 
 # Enable this setting to ask systemd to watch over MPD, see
 # systemd.service(5).  This is disabled by default because it causes
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/systemd/user/mpd.service.in 
new/mpd-0.23.4/systemd/user/mpd.service.in
--- old/mpd-0.23.3/systemd/user/mpd.service.in  2021-10-31 18:13:10.000000000 
+0100
+++ new/mpd-0.23.4/systemd/user/mpd.service.in  2021-11-11 10:16:36.000000000 
+0100
@@ -5,11 +5,7 @@
 
 [Service]
 Type=notify
-ExecStart=@prefix@/bin/mpd --no-daemon
-
-# Create /run/user/$UID/mpd (if MPD is launched without the socket
-# unit and is configured to bind listener sockets there).
-RuntimeDirectory=mpd
+ExecStart=@prefix@/bin/mpd --systemd
 
 # Enable this setting to ask systemd to watch over MPD, see
 # systemd.service(5).  This is disabled by default because it causes
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mpd-0.23.3/win32/build.py 
new/mpd-0.23.4/win32/build.py
--- old/mpd-0.23.3/win32/build.py       2021-10-31 18:13:10.000000000 +0100
+++ new/mpd-0.23.4/win32/build.py       2021-11-11 10:16:36.000000000 +0100
@@ -99,6 +99,7 @@
     libid3tag,
     liblame,
     libmodplug,
+    libopenmpt,
     wildmidi,
     gme,
     ffmpeg,

++++++ mpd-conf.patch ++++++
--- /var/tmp/diff_new_pack.wxl7FG/_old  2021-11-13 22:49:08.281278130 +0100
+++ /var/tmp/diff_new_pack.wxl7FG/_new  2021-11-13 22:49:08.281278130 +0100
@@ -1,5 +1,6 @@
---- mpd-0.22.4.orig/doc/mpdconf.example        2021-01-21 19:21:20.000000000 
+0300
-+++ mpd-0.22.4/doc/mpdconf.example     2021-01-23 14:43:26.000000000 +0300
+diff -Pdpru mpd-0.23.4.orig/doc/mpdconf.example mpd-0.23.4/doc/mpdconf.example
+--- mpd-0.23.4.orig/doc/mpdconf.example        2021-11-11 12:16:36.000000000 
+0300
++++ mpd-0.23.4/doc/mpdconf.example     2021-11-13 01:39:07.843410617 +0300
 @@ -17,7 +17,7 @@
  # playlist files not created by the server but only if they are in the MPD
  # format. This setting defaults to playlist saving being disabled.
@@ -15,23 +16,25 @@
  #
 -#db_file                      "~/.mpd/database"
 +#db_file                      "/var/lib/mpd/mpd.db"
- #
+ 
  # These settings are the locations for the daemon log files for the daemon.
- # These logs are great for troubleshooting, depending on your log_level
-@@ -34,25 +34,25 @@
- # The special value "syslog" makes MPD use the local syslog daemon. This
- # setting defaults to logging to syslog.
  #
--#log_file                     "~/.mpd/log"
-+log_file                      "/var/log/mpd.log"
+@@ -35,7 +35,7 @@
+ # If you use systemd, do not configure a log_file.  With systemd, MPD
+ # defaults to the systemd journal, which is fine.
  #
+-#log_file                     "~/.mpd/log"
++#log_file                     "/var/log/mpd.log"
+ 
  # This setting sets the location of the file which stores the process ID
  # for use of mpd --kill and some init scripts. This setting is disabled by
- # default and the pid file will not be stored.
+@@ -43,19 +43,19 @@
  #
--#pid_file                     "~/.mpd/pid"
-+pid_file                      "/run/mpd/mpd.pid"
+ # If you use systemd, do not configure a pid_file.
  #
+-#pid_file                     "~/.mpd/pid"
++#pid_file                     "/run/mpd/mpd.pid"
+ 
  # This setting sets the location of the file which contains information about
  # most variables to get MPD back into the same general shape it was in before
  # it was brought down. This setting is disabled by default and the server
@@ -48,7 +51,7 @@
  #
  
###############################################################################
  
-@@ -64,14 +64,14 @@
+@@ -67,14 +67,14 @@
  # initialization. This setting is disabled by default and MPD is run as the
  # current user.
  #
@@ -65,7 +68,7 @@
  #
  # This setting sets the address for the daemon to listen on. Careful attention
  # should be paid if this is assigned to anything other than the default, any.
-@@ -82,7 +82,7 @@
+@@ -85,7 +85,7 @@
  #bind_to_address              "any"
  #
  # And for Unix Socket
@@ -74,7 +77,7 @@
  #
  # This setting is the TCP port that is desired for the daemon to get assigned
  # to.
-@@ -93,7 +93,7 @@
+@@ -96,7 +96,7 @@
  # troubleshooting. Available setting arguments are "notice", "info", 
"verbose",
  # "warning" and "error".
  #
@@ -83,7 +86,7 @@
  #
  # Setting "restore_paused" to "yes" puts MPD into pause mode instead
  # of starting playback after startup.
-@@ -117,7 +117,7 @@
+@@ -120,7 +120,7 @@
  # This setting enables automatic update of MPD's database when files in
  # music_directory are changed.
  #
@@ -92,7 +95,7 @@
  #
  # Limit the depth of the directories being watched, 0 means only watch
  # the music directory itself.  There is no limit by default.
-@@ -147,7 +147,7 @@
+@@ -150,7 +150,7 @@
  # If this setting is set to "yes", service information will be published with
  # Zeroconf / Avahi.
  #
@@ -101,7 +104,7 @@
  #
  # The argument to this setting will be the Zeroconf / Avahi unique name for
  # this MPD server on the network. %h will be replaced with the hostname.
-@@ -214,8 +214,9 @@ input {
+@@ -217,8 +217,9 @@ input {
  #
  #audio_output {
  #     type            "alsa"
@@ -109,11 +112,17 @@
 -##    device          "hw:0,0"        # optional
 +#     name            "ALSA Device"
 +##    device  "plug:plugequal"        # optional
-+##    mixer_control   "Master"                # optional
++## mixer_control      "Master"                # optional
  ##    mixer_type      "hardware"      # optional
  ##    mixer_device    "default"       # optional
  ##    mixer_control   "PCM"           # optional
-@@ -243,9 +244,9 @@ input {
+@@ -241,14 +242,14 @@ input {
+ #audio_output {
+ #     type            "shout"
+ #     encoder         "vorbis"                # optional
+-#     name            "My Shout Stream"
++#     name            "Shout Stream"
+ #     host            "localhost"
  #     port            "8000"
  #     mount           "/mpd.ogg"
  #     password        "hackme"
@@ -126,16 +135,16 @@
  ##    protocol        "icecast2"              # optional
  ##    user            "source"                # optional
  ##    description     "My Stream Description" # optional
-@@ -263,34 +264,34 @@ input {
+@@ -266,34 +267,34 @@ input {
  #     name            "My recorder"
  #     encoder         "vorbis"                # optional, vorbis or lame
  #     path            "/var/lib/mpd/recorder/mpd.ogg"
 -##    quality         "5.0"                   # do not define if bitrate is 
defined
 -#     bitrate         "128"                   # do not define if quality is 
defined
 -#     format          "44100:16:1"
-+#     quality         "6.0"                   # do not define if bitrate is 
defined
-+##    bitrate         "192"                   # do not define if quality is 
defined
-+##    format          "48000:16:2"    #optional
++##    quality         "6.0"                   # do not define if bitrate is 
defined
++#     bitrate         "192"                   # do not define if quality is 
defined
++#     format          "48000:16:2"
  #}
  #
  # An example of a httpd output (built-in HTTP streaming server):
@@ -147,16 +156,14 @@
 +#     name            "HTTP Stream"
 +#     encoder "vorbis"                # optional, vorbis or lame
  #     port            "8000"
--#     bind_to_address "0.0.0.0"               # optional, IPv4 or IPv6
+ #     bind_to_address "0.0.0.0"               # optional, IPv4 or IPv6
 -##    quality         "5.0"                   # do not define if bitrate is 
defined
 -#     bitrate         "128"                   # do not define if quality is 
defined
 -#     format          "44100:16:1"
--#     max_clients     "0"                     # optional 0=no limit
-+#     bind_to_address "0.0.0.0"       # optional, IPv4 or IPv6
-+#     quality         "6.0"                   # do not define if bitrate is 
defined
-+##    bitrate         "192"                   # do not define if quality is 
defined
-+##    format          "48000:16:2"    #optional
-+##    max_clients     "0"                     # optional 0=no limit
++##    quality         "6.0"                   # do not define if bitrate is 
defined
++#     bitrate         "192"                   # do not define if quality is 
defined
++#     format          "48000:16:2"
+ #     max_clients     "0"                     # optional 0=no limit
  #}
  #
  # An example of a pulseaudio output (streaming to a remote pulseaudio server)
@@ -175,16 +182,16 @@
  #
  # An example of a winmm output (Windows multimedia API).
  #
-@@ -352,7 +353,7 @@ input {
+@@ -355,7 +356,7 @@ input {
  #     command         "AudioCompress -m | aplay -f cd 2>/dev/null"
  ## Or to send raw PCM stream through PCM:
  #     command         "nc example.org 8765"
 -#     format          "44100:16:2"
-+##    format          "48000:16:2"    # optional
++#     format          "48000:16:2"
  #}
  #
  ## An example of a null output (for no audio output):
-@@ -410,6 +411,6 @@ input {
+@@ -413,6 +414,6 @@ input {
  # If file or directory names do not display correctly for your locale then you
  # may need to modify this setting.
  #

++++++ mpd-user.conf ++++++
--- /var/tmp/diff_new_pack.wxl7FG/_old  2021-11-13 22:49:08.309278151 +0100
+++ /var/tmp/diff_new_pack.wxl7FG/_new  2021-11-13 22:49:08.309278151 +0100
@@ -2,7 +2,7 @@
 playlist_directory      "~/.mpd/playlists"
 db_file                 "~/.mpd/database"
 log_file                           "~/.mpd/log"
-pid_file                           "~/.mpd/pid"
+#pid_file                          "~/.mpd/pid"
 state_file                         "~/.mpd/state"
 sticker_file                   "~/.mpd/sticker.sql"
 bind_to_address                    "127.0.0.1"

Reply via email to