This reverts commit 94b5b9f370. It was
not necessary for branch v0.23.x because there, Break() is
thread-safe; this was only changed later by commit
a3b32819b1
snd_pcm_poll_descriptors_revents() may return any error code; the
ALSA docs do not constrain the permitted values. A 'hw' device
will only ever return an error if the pfd array passed in is
invalid (-EINVAL), but other I/O plugins may return arbitary
errors. For example a network-based device may return -EPIPE etc.
The resulting exception thrown by
AlsaNonBlockPcm::DispatchSockets() must be caught to prevent the
mpd process from being aborted.
Some ALSA capture devices can have very large buffers, holding 10
seconds or more audio. Using the maximum buffer size with such
devices leads to unacceptably large, and unnecessary, latency.
Also, some ALSA drivers (e.g. HDA Intel PCH) report an invalid
maximum period size, and the period size that mpd calculates from
the maximum buffer size results in "Invalid argument" error when
applying the hw_params. Note that the "default" capture device on
many cards includes the "dsnoop" plugin which imposes a buffer
size of 16384 frames, so that "alsa://" works OK but
"alsa://plughw" or "alsa://hw" both fail.
Limit the maximum buffer time for ALSA input devices to a more useable
2 seconds, thereby avoiding both the above problems.
6d91b5c7b2 ("fix double promotions") changed
how LAME peak values are decoded, producing large incorrect values that
cause some MP3 files to play silently.
Restore the original decode from MAD fixed-point format to double and
document what it's doing.
Fixes#1823
Let OnHeaders() check the status.
The status checking code was added by commit 4f021cbced in 2011,
but in 2008, commit a8e81326d0 enabled `CURLOPT_FAILONERROR`, which
means the status checking code never had any effect.
This allows `LoadExcludeListOrLog()` to hide boring "404 Not Found"
log messages via `IsFileNotFound()`.
The `assert(!quit)` can fail if the `EventThread` gets stopped before
it enters `EventLoop::Run()`. There is a similar problem with `alive`,
which gets reset by `EventThread::Stop()`.
If that happens, then `EventLoop::Run()` should return immediately
without handling any events.
Without clearing all `in_playlist` flags, the songs will never be
revealed again if they were hidden once by a CUE sheet, not even after
the CUE sheet gets deleted or modified.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1784
This adds `MakeFfmpegError()` to the executable and fixes a linker
failure when `libavutil` is available, but `libavformat` and
`libavcodec` are not.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1786
Otherwise, building will generate these warnings:
systemd/system/meson.build:5: WARNING: Project targeting '>= 0.56.0' but tried to use feature deprecated since '0.56.0': Dependency.get_pkgconfig_variable. use Dependency.get_variable(pkgconfig : ...) instead
systemd/user/meson.build:5: WARNING: Project targeting '>= 0.56.0' but tried to use feature deprecated since '0.56.0': Dependency.get_pkgconfig_variable. use Dependency.get_variable(pkgconfig : ...) instead
libfmt 10 doesn't know how to format a StringView, and doesn't cast to
std::string_view anymore. The StringView class has been removed from
MPD 0.24 completely, and this is a stable-branch-only workaround.
Closes https://github.com/MusicPlayerDaemon/MPD/pull/1814
This should prevent ffmpeg from taking priority over the gme plugin.
The ffmpeg plugin is more buggy than gme.
One of the prominent bugs of preferring ffmpeg over gme is that ffmpeg
cannot seek SAP files while gme can. This should prevent that from
happening.
libfmt version 10 apparently doesn't know how to format a
`StringBuffer`, failing the MPD build. Since we have a formatter
specialization for `AudioFormat`, let's use that - it's better and
easier to use.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1807
Fixes hide_playlist_targets not working after server restart
Currently, `hide_playlists_targets` works by skipping songs with
`in_playlist` value set to true in
[`Directory::Walk`](a57bcd0238/src/db/plugins/simple/Directory.cxx (L237)). But
`in_playlist` is not stored and only updated in
[`UpdateWalk::PurgeDanglingFromPlaylists`](a57bcd0238/src/db/update/Playlist.cxx (L139)),
which will only be executed while updating DB.
This causes the problem that playlist target songs are correctly
hidden after database update, but will remain visible after mpd server
restarted. This pr solves the problem by storing `in_playlist` value
of songs into the `SimpleDatabase` file.
By default, if the parent of a process dies, the process gets SIGHUP
and is supposed to shut down. This however doesn't work for MPD,
because MPD redefines SIGHUP with a different meaning (like most
daemons do).
To work around this, we configure the kernel to send SIGTERM instead
of SIGHUP.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1706
Fixes a busy loop in BufferingInputStream::RunThreadLocked() because
the method never learns that seeking is ignored, even though the HTTP
stream is already broken and can never be read; nobody cared to check
for errors.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1727
If the environment variable $HOME does not exist, don't attempt to
obtain it from /etc/passwd; without $HOME, the calling process
indicates that it does not wish MPD to access the home directory.
This also prevents MPD from attempting to load
`/root/.config/mpd/mpd.conf` if MPD got started as global systemd
service. Reading from there makes no sense, only /etc/mpd.conf shall
be used then.
This piece of code was initially added by commit 5d85792178.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1687
When drop_start_samples and drop_end_samples overlap and are greater
than the actual number of samples, the `num_samples` calculation in
SubmitPCM() could underflow.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1712
Fix build with Boost 1.81.0. `<array>` was included by one of those boost headers,
however, it's no longer included as of Boost 1.81.0.
`master` doesn't use `std::array` in this file.
While we're at it, add all necessary inclusion files.
These settings do not work if CURL was compiled with
CURL_DISABLE_PROXY, and cause error "An unknown option was passed in
to libcurl".
Fixes regression by commit 7ab0dfc8ce
Of course, mode=0700 is more secure, but allowing other users access
to new directories is a choice the user should make via umask(). If
the user-chosen umask allows everybody access, MPD should probably
respect that.
The function spl_valid_name() should verify playlist names and prevent
path traversal, but it failed to do so on Windows, because it forgot
to check for backslashes.
This buggy piece of code was already present when stored playlists
were initially implemented in 2006 by commit 08003904d7, and
even during the many rounds of code refactoring, nobody ever bothered
to verify it. D'oh!
(Thanks, Paul Arzelier)
snprintf() does not return the (truncated) length actually written,
but the length that would be needed if the buffer were large enough.
This API usage mistake in FormatLastError() can lead to overflow of
the stack buffer, crashing the process (Windows only).
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1676
If no archive library was found, return from the "plugins" directory
without creating "libarchive_plugins.a". Empty static libraries are
unsupported on some operating systems such as macOS.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1650
According to the latest WebDAV specification (RFC4918),
timestamp string in the getlastmodified property is formatted
as rfc1123-date, such as "Sun, 06 Nov 1994 08:49:37 GMT".
However, to process responses from servers in the older style
format specified in RFC2518, timestamps in the HTTP-date format
had better be accepted.
As described in the libcurl api documentation, curl_getdate() can handle
timestamp strings in HTTP-date formats, including rfc1123-date.
https://www.rfc-editor.org/rfc/rfc4918#section-15.7https://www.rfc-editor.org/rfc/rfc2518.html#section-13.7https://curl.se/libcurl/c/curl_getdate.html
This fixes a bug introduced in 87fa6bca where the FLAC encoder fails to
initialize unless libFLAC is built with Ogg support. When libFLAC is
built without Ogg support, FLAC__stream_encoder_set_ogg_serial_number
unconditionally returns false.
Calling data[fill] could trigger an assertion failure if
fill==data.size(), even if we call it only to take the address.
Instead of doing that, this commit changes the code to pointer
arithmetic.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1556
occurrences of the word Master/master with Main/main. This change was test built on two different systems.
1. macos 10.15.7 with Xcode 12.4 and clang 12.0.0 on x86_64
2. macos 12.5 with Xcode 13.4.1 and clang 13.1.6 on arm64 (Apple silicon M1)
It should be noted that on macos 10.15.7 with Xcode 11.2 and clang 11.0, MPD will not build.
The MPD documentation states that clang 11.0 is the minimum requirement,
but clang 11.0 produces compile errors. Apparently the macos version
of clang 11.0 is not fully compliant.
Properly deals with iconv, unlike the current solution. have_iconv fails
when libiconv CFLAGS are passed to the compiler. Tested under OpenWrt
with its CONFIG_BUILD_NLS, which adds libiconv include flags.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
Deactivate the stream in Cancel(). This fixes stuttering after a
manual song change by refilling the whole ring buffer before
reactivating the stream.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1354
Clear not only MPD's ring buffer, but also libpipewire's buffers, to
avoid playing some audio from the previous song after a manual song
change.
Fixes part 1 of https://github.com/MusicPlayerDaemon/MPD/issues/1354
Removing the LockHasClients(); this code was copied from the "httpd"
output plugin, but unlike "httpd", the SnapCast output plugin does not
feed silence while paused, so we need to implement a delay to avoid
busy-looping the CPU.
As a side effect, this eliminates the suttering after resuming
playback, because the timer now gets reset even if there is a client.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1394
Since PipeWire 0.3.53, there is no control name anymore, therefore the
name check doesn't work anymore, breaking volume change events.
This obsoletes the crash bug fix in commit 2ee57f9b0d
If the PipeWire output has not yet been enabled and no thread_loop has
been created yet, a nullptr dereference in SetVolume() was possible
because nullptr was passed to pw_thread_loop_lock().
If a mixer is not open, rethrow the original exception each time
setting the volume is requested. This further improves error messages
sent to MPD clients.
This fixes a std::terminate() crash in the CURL storage plugin when
PropfindOperation::OnHeaders() throws an exception after receiving a
non-207 status.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1559
strlen() and strcpy() are provided by the <string.h> and <cstring>
headers (as functions in global and std namespaces, respectively).
Compilers MAY provide an implementation for either of the functions
without including the extra header but the existence of a declaration
without the header is not assured.
This issue occurs when playing HLS streaming delivered
from a server that does not support partial requests.
The issue is reproduced as follows(using Ubuntu 20.04 PC):
1. Prepare HLS example content.
$ mkdir test
$ ffmpeg -i example.flac -vn -c:a aac -b:a 128000 -f hls -hls_list_size 0 test/output.m3u8
(ffmpeg 4.2.4 is used)
2. Prepare web server without partial requests support.
(Docker version 20.10.12 and NGINX official Docker image is used)
$ docker run --name tmp-nginx-container -d nginx
$ docker cp tmp-nginx-container:/etc/nginx/conf.d/default.conf .
$ docker rm -f tmp-nginx-container
Edit default.conf and add "max_ranges 0;" to "location / {...}".
This disables partial requests support,
removes 'Accept-Ranges: bytes' header from the server response.
Then, run the server:
$ docker run --name test-nginx -v $PWD/test:/usr/share/nginx/html:ro -v $PWD/default.conf:/etc/nginx/conf.d/default.conf -d -p 8080:80 nginx
3. Setup MPD to Play the next URL.
http://address-of-the-server:8080/output.m3u8
Seeking this stream results in "exception: Not seekable".
Even if the "wave_encoder" option is disabled (and no other encoder
plugins are enabled), forcefully enable the Wave encoder (if Snapcast
is enabled).
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1500
This script setup a dummy android native app folder and call ndk-gdb from it.
It needs a modification in ANDROID_NDK since ndk-gdb may attach to the wrong
pid, cf. comments in the script.
Previous versions of MPD would call SetVolume on enabled outputs before
they are ready, causing all of MPD to crash. Checking the really_enabled
flag prevents this, though it also prevents setting volume before the
player starts.
Before (with the PipeWire output):
[i] ~$ mpc clear
volume: 81% repeat: off random: off single: off consume: off
[i] ~$ systemctl --user restart mpd.service
[i] ~$ mpc volume 100
MPD error: Connection closed by the server
[i] ~ 1 $
After:
[i] ~$ # mpd is freshly started w/o anything in the queue
[i] ~$ mpc
volume:100% repeat: off random: off single: off consume: off
[i] ~$ mpc volume 80
MPD error: problems setting volume
[i] ~ 1 $ mpc
volume:100% repeat: off random: off single: off consume: off
[i] ~$
Previous versions of MPD would, on parameter change, set the PipeWire
volume before clearing the restore_volume flag, causing the call to
short circuit and do nothing. Instead, clear the flag before the call.
Move audio output state check ahead of mixer check and force volume
applying even for disabled software mixed outputs.
This fixes incorrect software mixer volume that used to occur when
volume was changed while output being disabled.
This is easily reproduced with following sequence of commands on
multi-output software mixed MPD setup.
mpc volume 38; mpc disable 3; mpc volume 88; mpc enable 3
On current MPD, following commands would result in output 3 playing at
volume 38, while all other enabled outputs would play at volume
88. Moreover, global volume would display average of outputs real
volumes. In my case, it's 75.
After applying this patch, following commands would produce expected
behavior. All outputs play at expected (88) volume. And volume is
correctly displayed as 88.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1423
Signed-off-by: Vitaly Ostrosablin tmp6154@yandex.ru
Signed-off-by: Vitaly Ostrosablin <tmp6154@yandex.ru>
In libFLAC 0.3.4 (commit c9530118a4), 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.
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
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.
The writing and reading of metadata involves lots of different programs
and libraries. Therefore it is prudent to point out how exactly MPD
receives metadata. Ideally this helps to point users to the right place
if their tags are not picked up correctly.
lib/src/libmpdclient-2.19/meson.build:1:0: ERROR: Unknown options: "needs_exe_wrapper"
The "needs_exe_wrapper" option was incorrectly set under
[built-in options] rather than [properties].
Improves the changes made in 57687779be by
using AudioManager.ACTION_AUDIO_BECOMING_NOISY rather than listening for
wired headset unplug events or Bluetooth headset disconnect events. This
method is more flexible, allowing the feature to work on other types of
audio output device, as well as Bluetooth devices that don't set their
device class correctly. This change also has the benefit of being more
responsive, pausing the audio before it is rerouted to the built-in
speaker.
https://developer.android.com/guide/topics/media-apps/volume-and-earphones
With large "max_playlist_length" settings, the "data" array can be
very large, and initializing it during MPD startup causes page faults,
resulting in allocation of physical RAM. This commit postpones the
initialization until the queue is really large, to avoid wasting
memory.
SonarLint reports the latter to be better:
std::scoped_lock basically provides the same feature as std::lock_guard,
but is more generic: It can lock several mutexes at the same time, with a
deadlock prevention mechanism (see {rule:cpp:S5524}). The equivalent code
to perform simultaneous locking with std::lock_guard is significantly more
complex. Therefore, it is simpler to use std::scoped_lock all the time,
even when locking only one mutex (there will be no performance impact).
Signed-off-by: Rosen Penev <rosenp@gmail.com>
This reverts commit 552c30eae4.
It has caused various problems; for example, MPD wasn't able to write
the pid_file (which was already mitigated by commit a4e4217204).
And apparently, the socket file created in the same directory by
mpd.socket disappears when mpd.service (re)creates the directory. I
could not reproduce this problem with 247.3, but maybe this is a bug
in older systemd versions?
Until we figure out why this happens, let's remove the
RuntimeDirectory directive. A future MPD version may be launched as
regular user, not as root, which will eliminate one major problem with
RuntimeDirectory.
Add an option to the UPnP database plugin to configure which interface
is used by upnp to discover servers.
upnp by default selects the first interface that is not loopback, which
in some cases might not be the desired interface. For example if wanting
to access a DLNA server over a VPN connection.
The "interface" option can now be set to the name of the desired
interface to achieve this.
The default behaviour remains unchanged.
Adds the Interface Name as an argument to the *Init functions to make it
possible to select which interface is used by upnp to detect servers.
Currently "nullptr" is passed in to let the upnp library select an
interface, as before.
Commit 552c30eae caused problems for those people who still had a
"pid_file" setting (even though that is obsolete with systemd),
because now /run/mpd is owned by root:root (our mpd.service has no
User=mpd directive, so systemd starts MPD as root).
To work around this problem, and to be able to keep
RuntimeDirectory=mpd (which solved a problem of other MPD users), the
best compromise seems to just ignore the "pid_file" setting when it is
of no use.
This way, MPD can reliably detect whether it was started as systemd
service, which is better than checking sd_booted(), which only checks
whether systemd manages all services, but still MPD could be started
manually.
This uncomments the code which had been present already in the first
Snapcast commit (copied from the "httpd" output plugin), but I
commented it because I did not know whether I needed to send silence
samples to all Snapcast clients.
As a side effect, this fixes playback when no Snapcast client is
connected; this was broken because Pause() always returned a positive
value when there were no clients.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1310
Unlike GetFilenameSuffix(), uri_get_suffix() removes the query string
first, which breaks file names with question marks in the name.
Therefore, uri_get_suffix() shall only be applied to remote URIs.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1316
Without clearing the "uri" field, the next Open() call attempts to
reuse the old InputStream, but it has already been closed, so Open()
always returns nullptr.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1300
With libfmt versions older than 7, this leads to an endless recursion
between Error() and FmtError(), resulting in a crash due to stack
overflow. D'oh!
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1295
During the libfmt migration, I converted "%1.3f" to just "{:1.3}"
without the "f" suffix, but libfmt defaults to scientific notation,
which can break some MPD clients.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1291
This replaces the output parameter (which is bad API design). As a
side effect, it fixes the bad [[gnu::pure]] attribute added by commit
a636d2127 which caused optimizing compilers to miscompile calls to
that function. "Pure" functions can be assumed to have no output
arguments, so the compiler can assume the function doesn't modify
them.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1282
Fixes https://github.com/MusicPlayerDaemon/MPD/discussions/1281
The problem occurred when there was libfmt-dev installed, but it was
too old (e.g. on Debian Buster), and Meson used the wrap fallback.
Those internal MPD libraries where the libfmt dependency was not
declared were still using the old system libfmt headers, which are not
ABI-compatible with MPD's own libfmt build.
From the feature request: "I generally like to have crossfade on, but
when it happens during such short tracks (e.g. 20 seconds or less) it
doesn't really sound good as those tracks are not really meant to be
crossfaded and intended to act as a bridge on their own."
Sounds reasonable. This commit doesn't add an option, but hard-codes
the limit to 20 seconds. If it turns out that users want to have it
configurable, we can still add the option.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1184
Now, "+0" means "right after the current song" and "-0" means "right
before the current song". Mnemonic: there are zero songs between the
current song and the newly added song.
A similar feature was present long ago in MPD, but was deprecated in
version 0.16 because the implementation was broken. This commit
re-adds the feature in a way that's well-defined and not broken.
Close https://github.com/MusicPlayerDaemon/MPD/issues/1221
NB: Check the sysconfdir setting to determine where mpd will look for mpd.conf; if you expect mpd to look for /etc/mpd.conf the sysconfdir must be '/etc' (i.e., not 'etc' which will result in mpd looking for /usr/local/etc/mpd.conf):
.. code-block:: none
meson configure output/release |grep sysconfdir
If this is not /etc (or another path you wish to specify):
.. code-block:: none
$ meson configure output/release -Dsysconfdir='/etc' ; meson configure output/release |grep syscon
sysconfdir /etc Sysconf data directory
The ChainFilter class is extremely complicated code, and will grow to
be even more complicated when the Filter interface gets extended.
Let's just remove it; we can easily chain many TwoFilters instead.
If DetectFilterOutputFormat() fails to determine the output format,
insert an "aformat" filter which attempts to force a specific output
format.
Fixes part 2 of of https://github.com/MusicPlayerDaemon/MPD/issues/1235
Don't truncate the FILETIME to second resolution to pass it to
std::chrono::system_clock::from_time_t(); instead, calculate the
offset between the FILETIME epoch and the
std::system_clock::time_point epoch, and use that to initialize the
time_point directly.
If draining was not requested, generate silence instead if there is no
data in the ring buffer.
The problem is that pw_stream_flush() appears to disable the stream
permanently, even though there is no state_changed callback - the
stream state remains at PW_STREAM_STATE_STREAMING, but the stream is
defunct. I have no idea why and I havn't found any documentation
about it.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1219
If UpdateStreamTag() gets called while an initial seek is pending, the
result will never be submitted to a MusicChunk. By avoiding the
UpdateStreamTag() call in that case (by moving UpdateStreamTag() to
after the PrepareInitialSeek() check), the song_tag is preserved until
UpdateStreamTag() is called again from SubmitData().
This fixes missing tags in the "httpd" output.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1137
Explanation
This adds support for DOP using the PcmExport function if the macro
ENABLE_DSD is defined. If enabled within the config-file using "dop",
the boolean dop_setting will be true. If DSD input is encountered and
the setting is on, it is checked whether the oss-device supports the
required samplerate. If that is the case, dop_active is set to true
and conversion of the input is prevented. If the sample rate is not
supported, conversion to S32 is requested. When playing back, the
PcmExport is used to pack the incoming stream into PCM. Reasoning
This is required for OSs without the required driver support for
native DSD playback that also have no ALSA. Mainly *BSD users are the
target audience for this functionality, as ALSA here is only a proxy
without full functionality. Requirements
DAC that supports the DOP standard
Building with OSS, DSD and S32-Format
Supported Formats / Required PCM Formats
DSF, DFF and WavPack-DSD will work.
DSD64, 1 Channel -> S24:176.4kHz (untested, lack of time / missing samples)
DSD64, 2 Channel -> S24:352.8kHz
DSD64, 4 Channel -> S24:705.6kHz (untested, lmissing equipment)
DSD128, 1 Channel -> S24:352.8kHz (untested, lack of time / missing samples)
DSD128, 2 Channel -> S24:705.6kHz
DSD256, 1 Channel -> S24:705.6kHz (untested, lack of time / missing samples)
Changes
inclusion of required files
adding new domain for logging
adding dop_satisfied private function
adding required member variables for storing dop state and for dop-packing
adding dop boolean parameter to many functions that are required to act a little differently when dop is active
Testing
This has been tested to work with a Sabaj Da2 on FreeBSD, where the
red status indicator LED clearly shows that DSD playback is taking
place, instead of purple for "hi-res" which is seen when converting.
Issues
I have not tested this with S24 and right now AFMT_S32_NE is
required. If not defined, ENABLE_DSD will be undef'ed. This will be
addressed in a bit, however no DAC which supports DOP but not 32Bit is
known to me. Also, AFMT_S32_NE is not defined when building on FreeBSD
which is why this is just blatantly defined in the file at the moment.
Additionally, the new dop-option is not added into any documentation
whatsoever.
We need this even when AFMT_S24_PACKED is not available, for the
correct channel order in multi-channel files. Internally, MPD uses
FLAC channel order, but OSS uses the same channel order as ALSA.
Also, use RemoveAll() instead of directly clearing TagBuilder::items in
most cases, as its elements represent references that must be released.
Closes#1023
ProxyInputStream::Read() assigns the `offset` field, which is the
wrong offset because it does not consider Icy metadata removed from
the stream. Therefore, after every ProxyInputStream::Read() call,
IcyInputStream::Read() needs to override this offset. This was
missing at the end of the stream, when Read()==0.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1216
Fixes
../git/src/Log.hxx:121:42: error: no member named 'forward' in namespace 'std'
LogFormat(LogLevel::ERROR, e, fmt, std::forward<Args>(args)...);
Signed-off-by: Khem Raj <raj.khem@gmail.com>
The script seems to assume package version numbers always end in numeric versions with an optional alpha-suffix. Alas, were it only so simple... Sometimes the package is called fizzbang-1.2.3+release_info in which case the build fails. No more!
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1177
Make sure that ZeroconfDeinit() gets called even if startup fails with
an exception. Fixes an assertion failure because an Avahi TimerEvent
is still active.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1192
These were added 11 years ago in commit 766b9fd453, but I cannot find
any evidence in the FFmpeg repository that these names were ever
supported. This commit adds the tags as they are currently present in
libavformat/mov.c.
For querying tags, the real song URI should be used, because if the
(display) URI is different, requesting it will not produce a usable
response. This is a theoretical problem because none of the existing
playlist plugins sets the real_uri.
This requires changing the URI comparison in playlist::TagModified().
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1154
With the default value CURLAUTH_ANY, libcurl needs to probe for
authentication methods first, and only the second request will have an
Authorization header.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1155
refactors GenerateOggSerial into a generic GenerateSerial
utility, under the util lib.
libFLAC may be encoded without Ogg support. If Ogg support is disabled,
libFLAC will still export Ogg-related methods (like setting a serial
number), and throw a runtime error when initializing an Ogg stream.
GenerateOggSerial does not depend on libogg. Refactoring it into
a generic GenerateSerial prevents having to add build-time checks
for libogg within the FLAC encoder plugin.
This enables the JACK output plugin on Windows, but doesn't link
against libjack64.dll, instead loads the DLL at runtime with
LoadLibrary(). This kludge avoids the extremely fragile JACK shared
memory protocol by using the system's libjack64.dll, without requiring
the same DLL at build time.
This reverts commit 1532983fb5. This
optimization was bad because now all strings match if they are a
prefix of another string, and this caused collisions in the tag string
pool, corrupting the database.
Add support for the following tags when using the proxy database plugin:
WORK
CONDUCTOR
LABEL
GROUPING
MUSICBRAINZ_WORKID
COMPOSERSORT
ENSEMBLE
MOVEMENT
MOVEMENTNUMBER
LOCATION
The current http output doesn't provide a header for cross-origin support. This prevents to use the mpd http stream directly from an other webapplication due the origin from the webpage differs from then the audio stream.
The fix is to add the following header to the http response:
Access-Control-Allow-Origin: *
This commit adds some tags that are (mostly) interesting for listeners
of classical music.
Ensemble
--------
This is an ensemble that is playing the music, such as Wiener
Philharmoniker. The tag can be used to distinguish the ensemble from the
conductor, composer, soloist, and ensemble, that are generally all in
the "ARTIST" tag.
Movement
-------
The movement number and movement (name) of this track, i.e. "II" and
"Allegro".
ComposerSort
------------
Allows us to look for Beethoven's 9th under B, for Beethoven, not L for
Ludwig.
Location
--------
This is the location of the recording, e.g. "Wiener Musikverein".
This code is complicated - and broken: the producer thread is not
allowed to call consumer methods. Also the code is not necessary
because this plugin implements Interrupt().
This finishes problems which occur early in the WasapiOutputThread;
previously, the error was ignored and the output blocked forever
without doing anything (and without reporting the error).
If an exception has been caught, the method cannot continue playback,
therefore it doesn't make sense to have the "catch" block inside the
"while" block (and not break the loop after catching an exception).
ParseTimePoint.
%Z is a glibc extension to strptime, and is a no-op there, due to the
mapping between timezone names and their definition (especially when the
name comes from a different machine) being ambiguous / impossible. Time
in HTTP headers is guaranteed to be UTC.
Passing an unknown format to strptime() implementations that don't
support it will generally cause them to return NULL, which will lead to
ParseTimePoint throwing an exception and ParseTimeStamp using an
unnecessary fallback.
Since the timezone name goes at the end of the string, we don't need to
use %Z to skip it (could be an issue in a different time stamp format),
so simply removing %Z works best.
By casting to SafeLinkIntrusiveListHook if appropriate, this fixes a
bug in the erase() method, where erase() calls
IntrusiveListHook::unlink() instead of
SafeLinkIntrusiveListHook::unlink().
If the constructor moves from an ExportedSong instance which refers to
somebody else's "Tag" instance, the newly constructed instance will
instead refer to its own empty "tag_buffer" field. This broke
SimpleDatabase::GetSong(), i.e. all songs on the queue restored from
the state file or added using the "addid" command.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1089
The "move" command doesn't allow open-ended ranges because they don't
make a lot of sense; moving an open-ended range is only possible if
the destination index is before the range, and in that case, the
client should be well aware how many songs there are.
Closes https://github.com/MusicPlayerDaemon/MPD/pull/1057
After commit 1afa33c3c7, an old bug was revealed:
SimpleDatabase::GetSong() constructs an ExportedSong instance by
moving the return value of Song::Export(), which causes the
LightSong::tag field to be dangling on the moved-from
ExportedSong::tag_buffer. This broke tags from CUE sheets.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1070
Add cacert option for curl plugin
add cacert option for Curl plugin. Allows to set cacert for curl lib
Added documentation line into doc/plugins.rst with explanation for cacert option
Commit 79b2366387 added the field `skip`
to support unaligned reads, but set the `offset` field to a wrong
value. This resulted in miscalculation of `remaining`, causing
an assertion failure.
The fix is to assign `offset` the correct value, but consider the
`skip` value in the assertion.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1067
I havn't yet figured out how to use Android's system CA certificates
with CURL/OpenSSL, so a temporary workaround is to disable verify_peer
by default. The data MPD transfers isn't extremely important, so the
servers's authenticity isn't extremely important either.
If an InjectEvent callback schedules a timer, the loop will restart,
but the "busy" flag is still false. The fix is to move the "again"
check before the "busy" setting.
The original base relative path was introduced due to an erroneous test
where the URL started with three slashes: "https:///" instead of two,
which led to implementing handling for such cases but broke the two
slashes case.
This fix removes the base relative path handling because with two
slashes the path is anyway always relative to the host (aka absolute
URI, without host).
This reverts 216f62ea14 and part of 74b2fc7fdc
Signed-off-by: Vincent Petry <PVince81@yahoo.fr>
Use uri_has_scheme to find out if the href in Webdav responses is absolute
to use the matching base path extraction.
Signed-off-by: Vincent Petry <PVince81@yahoo.fr>
There can be more than one propstat block each with their own status
code. We're only interested in the one with the 200 status, the found
properties.
This fixes parsing to make sure we process all propstat blocks instead
of just the last one, which might have a 404 status for not-found
properties.
Signed-off-by: Vincent Petry <PVince81@yahoo.fr>
Remove additional "a:prop" in PROPFIND request to match RFC 4918 section 9.1.3.
Added Content-Type header as the body is not a true multipart POST.
Signed-off-by: Vincent Petry <PVince81@yahoo.fr>
SocketEvent knows the FD is still open and is about to close it, so
it's unnecessary to rely on the kernel (via AbandonFD) to clean up the
epoll_wait list.
### Why this is relevant
- `AbandonFD` assumes that upon closing the socket, the FD will be automatically removed from the epoll list. That fd is associated with a reference to the `SocketEvent`, so this is an important and dangerous assumption to get wrong. In the case that the FD isn't immediately removed from the list by the kernel, the event loop can crash due to the `SocketEvent` being destroyed and it being a use-after-free bug at that point.
- If a socket FD happens to be duplicated, then closing the SocketEvent FD will not automatically remove it from epoll, and will trigger said bug/crash. It is only automatically removed when all FD references to the underlying socket/resource are closed?
- A `fork()` is one example where a socket FD can be duplicated and result in this situation.
- `CLOEXEC` might be considered mitigation for this but also introduces a race condition where the crash can occur between a `fork()` and `exec()` without additional synchronization to freeze the event loop.
One could argue the mpd event loop isn't fork-safe, and thus should be allowed to use `AbandonFD` however it likes. A decision on whether this is intended should probably be declared; but either way this fix seems appropriate in cases where `Abandon` isn't actually necessary. It also might be possible to fix `AbandonFD` to mark the `SocketEvent` as removed without using `EPOLL_CTL_DEL`?
[edit: made this dependent on HAVE_THREADED_EVENT_LOOP which is always
true for MPD, but not for ncmpc, for example - mk]
This reverts commit 7bc1c9925b. It
caused a crash with the ALSA plugin family (through
MultiSocketMonitor::ReplaceSocketList() and
MultiSocketMonitor::AddSocket()). Until we have a proper fix, the
assertion patch is reverted.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1020
Some FFmpeg filters change the sample format, and since MPD assumes
this never happens, this results in loud noise instead of music. This
commit finally implements the TODO comment by sending one frame of
silence to the filter and checking the output frame's format.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1009
Pass a std::string to PathTraitsUTF8::Relative(), implicitly casting
it to std::string_view. This selects the right overload which returns
std::string_view instead of `const char *`; the latter could return
`nullptr` which would cause the implicit conversion of the return
value to std::string_view to crash.
Regression caused by commits ead208987d and a98d627c0b.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/995
This allows users to disable the "CUE files as directories" feature
without having to disable the CUE playlist plugin completely. This
feature has been annoying some users.
It's been 9 years already, and there's no point in insisting on the 21
year old C standard. MPD doesn't have a lot of C code left, but why
not compile it with the latest language revision.
Since MPD is a long-running daemon, it doesn't make sense to use
dynamic binding. That allows the relocations to be read-only
("relro"), which a hardening feature.
The bug https://bugzilla.samba.org/show_bug.cgi?id=11413 makes MPD
crash after at most a minute of using the plugin. Since this bug is
five years old already and it doesn't look like it will ever be fixed,
all libsmbclient code in MPD is scheduled for removal. For now, the
plugin is disabled by default so people are less likely to hit the
crash bug.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/991
This got lost in commit 5d597a3646 (v0.21.19), but it was never
noticed because the state_file_interval was way too short due to
commit 3413d1bf23, fixed recently by commit 27cc7b352d
snprintf() is available on mingw, and the libnfs kludge broke the
build with mingw, because sprintf_s() was now both an inline function
and a "dllimport" function (because the macro renamed the inline
function snprintf() to sprintf_s() in mingw's stdio.h).
Fixes regression by commit 23d5a2b862 -
that commit always pretended that any Opus file has both track and
album gain, and thus disabled the fallback to the other if one is not
set.
This patch changes the logic to only submit ReplayGain if at least one
value is set, and apply the offset only to that value. If none is
available, then the new check in HandleAudio() will submit only the
output gain.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/977
Instead of using this as a base class implementing a virtual method,
the new class IdleEvent can be used as a variable, decoupling
IdleMonitor's internal state from the derived class.
This is similar to commit 30a5dd267b
which refactored TimeoutMonitor to TimerEvent.
By bit-wise ANDing the reported flags with GetScheduledFlags(),
ERROR/HANGUP always get cleared. This means the MPD event loop could
never report those conditions.
Oh no, 3413d1bf23 was broken! Instead of passing a number as
"seconds" to the duration constructor, it just abused the duration
constructor as cast operator, which caused custom state_file_interval
settings to be extremely short.
This allows canceling the blocking method LockWaitWriteAvailable(),
and thus allows breaking free of misbehaving ALSA drivers, avoiding a
MPD lockup.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/966
This allows interrupting the output thread (for some plugins which
implement this method). This way, operations can be canceled
properly, instead of waiting for some external entity.
clocale is part of C++11.
In practical terms, gcc's libstdc++ comes with its own locale defines
when the libc does not have them.
Also reworked to be dependent on !ANDROID.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
My concept with `class CancellableOperation` doesn't work properly,
because the kernel may continue to write to the given buffer as soon
as the read finishes.
To fix this, this commit adds `class ReadOperation` which owns the
buffer and the `struct iovec`. Instances of this class persist until
the read really finishes, even if the operation is canceled.
And un-deprecate "pause" without parameter (toggles pause). I have no
idea why it was deprecated long ago; the deprecation notice was copied
from the ancient MPD wiki.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/944
Similar to commit 4e2a551f30 but for
decoder plugins. This is tailored for the FFmpeg decoder plugin which
implements some protocols (e.g. RTSP) as demuxer plugin.
This fixes a spurious "single" mode bug which occurs when using "play"
or "seek" to start playback on the song that is currently paused: in
that case, the main thread never queues the next song, and at the end
of the song, the player thread exits Run(), stopping playback, and
after that, the main thread starts the next song without considering
"single" mode.
By calling OnPlayerSync(), we ensure that the main thread gets a
chance to queue the next song before the player thread exits the Run()
loop.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/850
The log levels have always been very confusing (and badly named), but
this was most confusing: if there's a log level called "default", why
is it not the default?
Closes https://github.com/MusicPlayerDaemon/MPD/issues/926
Oh the horror! This plugin cannot possibly ever have worked. It was
broken from the start, when it was added in commit 37796699cf nearly
twelve (!) years ago.
The plugin would always read at sector boundaries, so it could only
ever work at multiples of 2 kB.
MPD uses soxr with prefined resample recipes. Soxr also support defining a recipe your self.
This commit will support a custom recipe by changing the existing quality setting to "custom".
The same structs as the predefined recipes uses can now set by hand.
This will make the following settings available:
- precision 16|20|24|28|32 bits, example "28"
- phase_response - 0-100, example "45"
- passband_end - used bandwidth of source 80-99.7%, example "99.7.0"
- stopband_begin - anti aliasing 100.0+%, example "100".
- attenuation - signal reduciton in dB's, 0-30. example "3.0".
- flags "0" - additional bitmask with extra settings
The data is set in the structs soxr_quality_spec and soxr_io_spec (found in soxr.h).
This fixes the Windows build. Linking failed because some packages
(e.g. libFLAC) default to enabling `_FORTIFY_SOURCE`, which is broken
in recent mingw versions
(https://github.com/msys2/MINGW-packages/issues/5803).
While libsndfile doesn't like partial reads in the middle of a file
(see commit 95ac6071b9), it allows partial reads at the end of a file.
It doesn't pay attention to the file size when issuing a read.
Commit ecb67a1ed1 (MPD 0.18.12) was a regression: previously,
partial reads at the end of a file were possible, but switching to
decoder_read_full() made this an error condition. This way, a portion
at the end of each file was lost, leading to corruption with gapless
playback (https://github.com/MusicPlayerDaemon/MPD/issues/936).
This fix switches to the newly introduced function
decoder_read_much(), which does the same as the code before commit
ecb67a1ed1.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/936
Our AudioObjectGetPropertyDataT() wrapper throws exception on error,
and calling it from OSXOutput::Disable() can cause MPD crash due to
std::terminate().
Closes https://github.com/MusicPlayerDaemon/MPD/issues/932
install_man() is currently broken with Meson and doesn't support a
custom target argument.
The problem with this kludge is that both mpd.1 and mpd.conf.5 are
installed in /usr/share/man/man1/, but apparently, there's no solution
yet.
This allows automatic optional detection of Sphinx. This will be
useful when we start building the manpages with Sphinx, which many
users may want to have.
Mounting one storage URI twice on different mount points can lead to
conflicts with the database cache file, and it doesn't make a lot of
sense.
But most importantly, our udisks storage plugin will unmount the disk
from the kernel VFS, and if two exist, they will compete with each
others. We could (and should) fix this in the udisks storage plugin,
but for now, this workaround is good enough (and useful).
When mounting something over a directory that is already a mount
point, CompositeStorage::Mount() silently overwrites the previously
mounted storage, disposing it. After that, SimpleDatabase::Mount()
will fail and handle_mount() will roll back the
CompositeStorage::Mount() command, effectively unmounting what was
there before (and also leaking memory).
Closes https://github.com/MusicPlayerDaemon/MPD/issues/918
Bug #915 is about an I/O exception thrown where none was allowed,
leading to crash via std::terminate(). However, instead of catching
and logging the error inside the decoder plugin, it should be able to
propagate the I/O error to the MPD core, so MPD can avoid trying other
decoder plugins.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/915
This will keep track of AudioOutputUnitStart() and
AudioOutputUnitStop(). This will provide some separation between "not
(yet) (re)started" and "paused".
The formula in osx_output_score_sample_rate() to detect multiples of
the source sample rate was broken: when given a 44.1 kHz input file,
it preferred 16 kHz over 48 kHz, because its `frac_portion(16)=0.75`
is smaller than `frac_portion(48)=0.91`.
That formula, introduced by commit 40a1ebee29, looks completely
wrong. It doesn't do what the code comment pretends it does.
Instead of using that `frac_portion` to calculate a score, this patch
adds to the score only if `frac_portion` is nearly `0` or `1`. This
means that the factor is nearly integer.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/904
Since Meson 0.51, there are special build options for "native:true"
builds, prefixed with "build.". This change breaks cross builds
because `GenParseName.cxx` is no longer built with `-std=c++17`.
This patch adds defaults for "build.c_std" and "build.cpp_std".
Closes https://github.com/MusicPlayerDaemon/MPD/issues/890
A bug report (https://github.com/MusicPlayerDaemon/MPD/issues/912)
suggests that on Linux, reading on `cifs` files may rarely return 0 (=
end of file) before the end of the file has really been reached. But
that's just a theory which I need to validate, so this runtime check
shall catch this condition before the assertion in
DecoderBridge::Read() crashes MPD. Let's see.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/912
An assertion failure in UpdateQueuedSong() could trigger because the
`prev` parameter is always `nullptr`, but `queued` may be set. And in
fact, calling UpdateQueuedSong() is only necessary when the queued
song was edited, to re-queue it with the new range.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/901
When the client wants to seek, but the decoder has already finished
decoding the current song, the player restarts the decoder with an
initial seek at the new position. When this initial seek fails, MPD
pretends nothing has happened and plays this song from the start.
With this new flag, a restarted decoder marks the initial seek as
"essential" and fails the decoder if that seek fails.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/895
Before the advent of io_uring (commit dae8da7066), this didn't
matter, because the `FileInputStream` never called this. But
`UringInputStream` is derived from `AsyncInputStream`, and needs the
handler to signal completion.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/898
Passing `length+1` to `MultiByteToWideChar()` means the function may
fill the whole buffer with output data, and could theoretically
overwrite the null terminator. In practice, this will never happen,
but this way, it's slightly more correct.
Also, null-terminate after `MultiByteToWideChar()`, after we got the
real output length. Again, this would never have been a problem, but
who knows...
This branch isn't yet ready for level 3 (`-Wpedantic`) due to several
C++ violations (e.g. variable length arrays). These are already
cleaned up in the master branch (0.22).
The WildMidi project added the pkg-config file in version 0.3.3, but
unfortunately, Debian still doesn't ship it 4 years later:
https://bugs.debian.org/916631
However, for cross-compiling, the pkg-config file is very helpful.
Commit 60f957ed64 broken the GCC 7 build, but instead of working
around missing C++17 features in old compilers, let's update the
compiler version requirements.
This commit raises the clang requirement to version 5 because this is
the first version to support `constexpr` lambdas, to be used to
`Dsd2Pcm.cxx`.
Fixes regression from commit db93bb996c because
ParseMimeTypeParameters() assumed the items were null-terminated, but
after that commit, they were not anymore.
This is the final piece of the series to establish io_uring support on
Linux.
MPD doesn't need io_uring for its efficient bulk I/O support, but to
allow file I/O to be cancelled. This is a big problem on CIFS/NFS
mounts where processes sleep uninterruptable if the file server
disappears, deadlocking MPD.
With io_uring, a flaky NFS connection allows MPD to continue to work
(even though there are still deadlocks inside MPD which need to be
addressed).
This plugin does not yet use cancellable `open()` using
`IORING_OP_OPENAT`. This will be implemented later.
Lots of other optimization opportunities for io_uring are still
missing as well - for example the database update could benefit a lot,
but unfortunately, io_uring doesn't have `readdir()` support just yet.
Reduces unstripped size. stripped size is the same.
Also took the time to remove using std::placeholders.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
The command is used to configure the client's connection, and this
shouldn't require any permissions. The client should be able to do
that before sending a password.
The parser implemented in libmpdclient requires the first key-value pair
of the server response to be the file pair. This is due to the fact that
libmpdclient scan pairs sequentially and first attempts to extract the
file pair before parsing the currentsong response further. See:
5c751a761e/src/song.c (L559-L563)
Meta data encoded as pairs in the currentsong response will be ignored
if they are placed before the file pair in the response.
libnfs is compiled with `-D_FILE_OFFSET_BITS=64`, but Meson decides
not to enable this mode. We could force this mode, but then again,
these days, nobody should be using 32-bit Windows ... so this is a
kludge only for debugging with 32-bit WINE.
This fixes a freeze bug in the NFS input/storage plugins: when libnfs
auto-reconnets after a failure, it installs the new socket on the same
file descriptor number. MPD's attempt to unregister the old socket by
calling SocketMonitor::Steal() from NfsConnection::ScheduleSocket()
fails because the new/old socket number is not registered in epoll, so
epoll_ctl() returns ENOENT. The problem is that it left
`scheduled_flags`, and so subsequent Schedule() calls will use
`EPOLL_CTL_MOD`, which will fail again and again. Instead, we need to
use `EPOLL_CTL_ADD` to register the new socket.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/806
Closes https://github.com/MusicPlayerDaemon/MPD/issues/756
LINGUISTIC_IGNORECASE is unimplemented on Wine, but since we don't
have any locale support (yet), and we're using LOCALE_NAME_INVARIANT,
NORM_IGNORECASE should essentially be the same, so why bother.
Unescape the base path and the path coming from the server (href) to fix the
comparison when the server uses different escaped characters.
The outputted name need to be unescaped. Doing that before or after the
HrefToEscapedName() call should not change the current behavior.
If the file name is "Hello & bye", 3 CharacterData events will be sent with the
State::HREF state:
- "Hello%20"
- "&"
- "%20bye"
Reproduced with files hosted on an apache2 DAV server: 2.4.38-3+deb10u3.
The _GLIBCXX_USE_C99_MATH macro is defined in glibcxx by c++config.h, which
gets included by every header. Which means a header needs to be present.
(cherry picked from commit 79e9aff338)
std::all_of becomes constexpr in C++20. I'm not sure it results in better
performance.
Found with useStlAlgorithm
Signed-off-by: Rosen Penev <rosenp@gmail.com>
This method gets called a lot during MPD startup, via FindChild() and
directory_load_subdir(), so this is worth optimizing at the expense of
code readability.
This speeds up MPD startup by 10%.
This reverts commit eb192137d6.
This is no longer necessary because we require FFmpeg 3.1 or newer
since MPD 0.21.2.
This fixes a deprecation warning because the implicit AVPacket copy
constructor copies the deprecated attribute `convergence_duration`.
_exit and std::_Exit are identical, expect the latter is standard C++.
Added several functions to the std namespace as a result of headers.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
This seems to be required on recent Android versions (tested with Android 10).
This is also required for android TV services (cf. next commit).
This is done using Java reflection so that the project doesn't depend on
android compat libs.
This is the case with uClibc-ng currently.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
(cherry picked from commit 769cd0ee9f0cf8ceb026aa751b5d4a390bb5dbdc)
(changed define to match master)
This has nothing to do with uClibc. It has everything to do with gcc's
libstdc++.
C99 math can be compile time disabled for it. Check for that and use boost
lround when std is not available.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
lrint is a configurable version of lround that behaves either as round,
floor, ceil, or trunc based on setting the proper FE_ macro using
fset/getround. Given that it's not set at all and that it defaults to
round behavior, simply replace with round.
Also removed the util/Math defines.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
The entire section falls under the else path of #ifdef _WIN32. Checking
for it makes no sense. Probably some refactoring mistake.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
Documentation says the limit is 5, but it was really 10 (at least
since 2004). But since MPD wants to promote using many small clients
idling around, and these clients consume only very few resources, it
seems reasonable to raise this limit's default value.
exp10 is a GNU function, is not part of C++, and is not available
everywhere.
pow(10,x) is an alternative that works just as well. It is used in musl as
the implementation of exp10.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
The former is deprecated by C++14. The standard says they are the same:
The header defines all types and macros the same as the C standard library
header<stdint.h>.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
The former is deprecated with C++14. The standard says both are the same:
The contents and meaning of the header<cstddef>are the same as the C
standard library header<stddef.h>,except that it does not declare the type
wchar_t, that it also declares the type byte and its associated
operations (21.2.5), and as noted in 21.2.3 and 21.2.4.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
The former was deprecated in C++14. The Standard says they are the same:
The contents of the header<cstdarg>are the same as the C standard library
header<stdarg.h>, with the following changes: The restrictions that ISO C
places on the second parameter to the va_start macro in header<stdarg.h>
are different in this International Standard. The parameter parmN is the
rightmost parameter in the variable parameter list of the function
definition (the one just before the...).219If the parameter parmN is a
pack expansion (17.5.3) or an entity resulting from a lambda capture
(8.1.5), the program is ill-formed, no diagnostic required. If the
parameter parmN is of a reference type, or of a type that is not
compatible with the type that results when passing an argument for which
there is no parameter, the behavior is undefined.
Also changed va_list to the std:: namespace version, which is the same.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
The former was deprecated with C++14. The standard says they are the same:
The contents of the header<csignal>are the same as the C standard library
header<signal.h>.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
The former was deprecated with C++14. The standard says they are the same
with one exception:
The header<climits>defines all macros the same as the C standard library
header<limits.h>.
[Note:The types of the constants defined by macros in<climits>are not
required to match the types to which themacros refer.— end note]
Signed-off-by: Rosen Penev <rosenp@gmail.com>
The former has been deprecated by C++14. They are also the same.
From the standard:
The contents and meaning of the header<cinttypes>are the same as the C
standard library header<inttypes.h>, with the following changes:
-The header<cinttypes>includes the header<cstdint>instead of<stdint.h>,and
—if and only if the typeintmax_tdesignates an extended integer type
(6.7.1), the following functionsignatures are added:intmax_t
abs(intmax_t);imaxdiv_t div(intmax_t, intmax_t);which shall have the same
semantics as the function signaturesintmax_t imaxabs(intmax_t)andimaxdiv_t
imaxdiv(intmax_t, intmax_t), respectively.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
The former is deprecated by C++14. It's also functionally the same.
From the standard:
19.4
The header<cerrno>is described in Table 43. Its contents are the same as
the POSIX header<errno.h>,except that errno shall be defined as a macro.
[Note: The intent is to remain in close alignment with the POSIX
standard.] A separate errno value shall be provided for each thread.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
None of the functions in these files come from ctype.h
Also changed one instance of isdigit to the C++ variant.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
The former was deprecated with C++14.
According to the C++11 and C++17 standards, both files are identical.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
Aparently, libcdio sometimes returns empty filenames, causing MPD
crashes. This shouldn't really happen, and I consider this a libcdio
bug - but if it happens, people blame MPD, so let's add a check.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/776
Fixes
../src/time/ISO8601.cxx:67:24: error: use of undeclared identifier 'strtoul'
unsigned long value = strtoul(s, &endptr, 10);
^
../src/time/ISO8601.cxx:77:14: error: use of undeclared identifier 'strtoul'
minutes = strtoul(s, &endptr, 10);
^
on NetBSD with clang 9.0.0.
Using libgme 0.6.2 on macOS, it appears that gme_info_t strings can be
empty, which creates weird track titles: (001/050)
This adds an additional check for an empty string.
"The issue is that ParseCommandArgSignedSongTime parses with
SongTime::FromS, not SignedSongTime::FromS, before casting back to a
SignedSongTime for the return. With x86 overflow rules this doesn't
matter, but on ARM the first cast turns negative values to zero."
Closes https://github.com/MusicPlayerDaemon/MPD/issues/757
This doesn't work because IterableSplitString() returns its elements
by value.
Fixes clang warning:
loop variable 'i' is always a copy because the range of type 'IterableSplitString' (aka 'BasicIterableSplitString<char>') does not return a reference [-Werror,-Wrange-loop-analysis]
When calling OggSeekFindEOS() from inside a OggVisitor callback, then
the #InputStream may be in the middle of an Ogg packet, and the newly
initialized #ogg_sync_state will not be able to load it without the
help of ogg_sync_pageseek(). By passing "synced=false" to
OggSeekFindEOS(), we force the use of ogg_sync_pageseek() even when
not actually seeking.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/719
This reverts commit c84bae739a. A
configuration option is not necessary, because the PcmConvert
constructor knows already whether integer or floating point is needed.
It appears that [[fallthrough]] is valid in C++ but not in C. And
in some Clang versions (e.g. Clang 11 on macOS), Clang is pedantic
about this and considers it an error to use [[fallthrough]] in a
.c file such as src/util/format.c.
This changes makes gcc_fallthrough a no-op under Clang in C files.
This reverts commit 4475b8ca04. Further
testing revealed that the threaded resolver still uses a timeout of
0ms. This revert however lowers the bound to a minimum of 1ms instead
of 10ms.
This prepares the migration away from strptime() for Windows
portability.
But the real reason I'm doing this is that strptime() on Apple is
buggy: strptime("14", "%H%M%S") (without separating colons) succeeds
even though only the hour has been parsed. This fixes recent Travis
failures in the ParseISO8601() unit test.
Older clang versions don't support the GCC __attribute__ syntax. For
those, don't use anything at all, and new clang versions shall use the
standard syntax.
Expand $PATH at evaluation and not at assignment, which fixes the
problem that /usr/lib/ccache was added to $PATH between the
MATRIX_EVAL assignment and its evaluation.
This can cause request completion in the I/O thread before this
constructor returns, leaving the object in an abstract state, causing
a crash due to pure virtual method call. We should not start the
request until this object is fully constructed.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/665
The ALSA "null" driver opens /dev/null and returns the file handle
from snd_pcm_poll_descriptors(), but /dev/null cannot be used with
epoll, the epoll_ctl() system call returns -EPERM. This means that
the ALSA output hangs, eventually freezing the whole MPD process.
This commit adds a workaround to the MultiSocketMonitor class which is
used by the ALSA output plugin.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/695
Most importantly, this commit translates ZZIP_ENOENT to
std::system_error(ENOENT) so IsFileNotFound() returns true and
find_stream_art() can suppress the log line.
This also reverts the previous commit which was wrong. When the
Vorbis decoder is disabled, we can't compile VorbisComments.cxx at
all.
Instead of expanding the #ifdef, this commit moves VorbisComments.cxx
to a separate library with dependencies on libvorbis (which was
missing previously, which could also lead to build failures if the
libvorbis headers were in a non-standard directory).
Commit 13208bf5a7 added range support to
the `move` command, but applied the wrong offset to the `to` variable.
When the source range is before the current song, and the song thus
gets decremented by the range size, then the final destination offset
must also be decremented by the range size.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/663
On linux-rt, kernel IRQ threads are configured with priority=50, and
this change configures MPD somewhat below that priority, leaving some
room for other programs to be configured in between.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/643
Without requesting the property, "good" WebDAV servers would not send
it, and so MPD could never recognize a directory, failing the database
update.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/660
Apparently, libmpcdec sets gain/peak variables to zero if they are not
present. This clashes with our formula and results in bogus values
which cause noise during playback.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/640
This commit adds a PlaylistPlugin attribute "as_folder" which for now
is only enabled in the "CUE" playlist plugin (which handles separate
"*.cue" files). If a playlist with this flag set is being scanned
during database update, it will be parsed and its contents will be
added to the database. This allows clients to inspect them like
directories and its contents will be searchable.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/39
This attribute is not a URI; it is just the filename without its
parent directory path. To avoid confusion, let's rename it to
"filename", leaving the struct without a "uri" attribute.
No longer allocate it as a "VarSize". This used to be a clever trick
to save memory 10 years ago, but these days, keeping the code
maintainable seems more important than saving a few kilobytes of
memory.
This header had been available for a long time on Linux, but was
removed in glibc 2.30. This commit moves the `#include` line inside
the `#ifdef __sun` block and adds a fake declaration of `I_FLUSH` for
the Linux build.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/630
This reverts commit 58d7804d66. It
caused a use-after-free bug when Client::OnSocketError() was called
due to a failed write, e.g. if the output buffer was full.
The new Response instance in the `catch` block didn't have the
`command` attribute set, so the error response didn't indicate which
command had failed, which however is required in the MPD protocol.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/628
This optimization is useless because sane pthread_cond_signal()
implementations check the number of waiters and do not invoke a system
call if there are none.
SID files are generally collections of tunes, so a SID name field makes
sense as an MPD album. The SID tune information list (STIL) has name
and title fields for individual tunes, when such are known, but MPD is
currently not using the STIL.
High Voltage SID Collection (HVSC) metadata fields are encoded in
windows-1252, as described in DOCUMENTS/SID_file_format.txt:
https://www.hvsc.c64.org/download/C64Music/DOCUMENTS/SID_file_format.txt
If utf-8 transcoding fails, or the ICU library is unavailable, fall
back to plain ASCII and replace other characters with '?'.
Version 10.2+0.93+1 was released five years ago in 2014 and is the
first version to feature cdio_cddap_free_messages(). There is no way
to check the libcdio-paranoia version at compile time, so let's just
remove support for older versions instead of attempting to fix the
cdio_cddap_free_messages() check at build time.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/613
This reverts commit f7ed7446ae. It was
a bad idea, because MAD_F_MIN and MAD_F_MAX do not represent the
clamping limits, but the theoretical minimum and maximum values of the
mad_fixed_t data type.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/617
Genres are not part of the SID format, so SID files are genreless. This
"default_genre" option may be used to assign a default genre to all SID
music, for example "SID", "C64", "Chiptune", etc.
This is useful in multiple mpd instances scenario, or multiple pulse outputs defined on the same mpd instance.
It is actually a more flexible way to route flows than the "sink" parameter, letting the PulseAudio routing do its job, but with the ability to isolate routing for each output.
If not specified, the role remains like it was before this commit, ie "music"
The check IsSeekableCurrentSong() was added by commit
44b200240f in version 0.20.19, but it
caused a regression: by doing the branch only if the current song is
seekable, the player would restart the current song if it was not
seekable, and later the initial seek would fail; but we already know
it's not seekable, and so we should fail early.
libmad has a hard-coded maximum PCM buffer size; if we make our
output_buffer just as large, we can avoid the loop, because any
possible size will fit.
libmad requires padding the input buffer with "MAD_BUFFER_GUARD" zero
bytes at the end of the file, or else it is unable to decode the last
frame.
This fixes yet another bug which prevented this plugin from decoding
the last frame, see
https://github.com/MusicPlayerDaemon/MPD/issues/601
The Xing/LAME frame indicates how many frames there are, but that
excludes the initial Xing/LAME frame. Therefore, it should not be
counted.
This fixes an off-by-one bug which caused the last frame to be
skipped, fixing one part of
https://github.com/MusicPlayerDaemon/MPD/issues/601
Applying software volume to S16 samples means several bits of
precision are lost; at 25% volume, two bits are lost. Additionally,
dithering adds some noise.
The problem gets worse when you apply the software volume code twice:
for the software mixer volume, and again for the replay gain. This
loses some more precision and adds even more dithering noise, which
can become audible (see
https://github.com/MusicPlayerDaemon/MPD/issues/542).
By converting everything to 24 bit, we need to shift only two bits to
the right instead of ten, losing nearly no precision, and dithering is
not needed. Even if the output device is unable to play S24 directly,
we can convert back to S16 with only one stage of dithering.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/542
Pass only the amount of data to PcmExport::Export() when its full
output fits into the ring buffer. Using only a part of the
PcmExport::Export() result may cause data corruption because
PcmExport's internal state may contain partial blocks which would need
to be rolled back when only some of its output data was used.
As a side effect, this fixes an assertion failure because
PcmExport::CalcInputSize() considered partial block data and could
cause Play() to return a number larger than the "size" parameter.
Fix src/ls.cxx to only print unique schemas.
Refactor src/ls.cxx to use src/input/InputPlugin functionality.
Add dynamic enumeration support to curl plugin.
MPD used to do that when this code lived in the player thread, but it
was removed by commit 98a7c62d7a4f716d90af6d78e18d1a3b10bc54b3; and
the replacement code in the ALSA output plugin didn't have it.
Without this timer, DispatchSockets() may disable the
MultiSocketMonitor and if Play() doesn't get called soon, it never
gets a chance to generate silence. However if Play() gets called,
generating silence isn't necessary anymore...
Resulting from this misdesign (added by commit ccafe3f3cf in 0.21.3),
the silence generator didn't work reliably.
In DispatchSockets(), when there was not enough data, but enough for
current playback, the method would disable the "active" flag so the
next Play() call would re-enable the MultiSocketMonitor.
This was an abuse of the flag which could result in a crash
in Cancel(), because that method asserts that the period_buffer is
empty, which it may be not.
The solution is to add anther flag called "waiting" which shares some
behavior with the old flag.
Apparently, if snd_pcm_drain() returns EAGAIN, it does not actually
want to be called again; the next call will snd_pcm_drain() will also
return EAGAIN, forever, even though the PCM state has meanwhile
switched to SND_PCM_STATE_SETUP. This causes a busy loop; to fix
this, we should always check snd_pcm_state() to see if draining is
really required.
This gives MPD more control, because attempts to avoid having partial
periods in the ALSA period buffer. For example, this means that
DrainInternal() doesn't need to generate silence to fill the partial
period.
Commit 1eae9339f2 added support for
multiple "groups" in the "list" command, and this change allows
clients to detect that this behavior, which had been documented for
several years, is now implemented properly.
Workaround for a regression caused by commit
a06bf388d9, revealing a problem with
discarding odd numer of frames in the DSD_U32 and DoP converters,
causing distortions with DSD_U32 and DoP on 32 bit CPUs.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/469
This can happen if the DoP converter doesn't get enough source samples
for one destination quad. This isn't a critical bug, because the OSS
plugin doesn't support DoP yet, but it's good to be prepared.
Instead of passing tag and group, pass an array of tags. To support a
nested return value, return a nested std::map of std::maps. Each key
specifies the tag value, and each value may be another nesting level.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/408
Add a `constexpr` constructor and several `constexpr` methods to
construct a DecoderPlugin at compile time, in a way which allows
adding new methods later without having to edit each plugin.
Eliminates a number of allocations, because callers don't need to copy
the strings to a newly allocated buffer only to null-terminate them.
And most callers don't need to have a null-terminated string.
Since we now don't duplicate all items, we can easily remove the 64kB
limit from OpusReader::ReadString() and instead silently ignore and
skip all strings which are longer than 4 kB.
This fixes a tag duplication bug with Opus file containing a very long
`METADATA_BLOCK_PICTURE` tag, which occurred because the Opus plugin
returned false after parsing all tags, and then the MPD core fell back
to FFmpeg which scanned the tags again.
Return `404 not found` for some common well-known paths, as clients requesting them usually do that automatically and don't expect endless audio stram.
Closes#572
Don't call Seek() if the stream is already at the beginning. This
avoids unnecessary exceptions if seeking is not implemented by an
Inputstream implementation.
This reverts commit ff3e2c0514. The
check was necessary, after all, because this is what checked whether
the decoder had finished the current or the next song.
> The "queued" flag can only possibly be set if the decoder is still
> decoding the current song or if the decoder is stopped.
That was wrong because ProcessCommand() sets `queued=true` and also
starts the decoder (if it was idle).
> This is also what the following assert() checks.
That was also wrong, because the assert() has two conditions.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/566
PluginUnconfigured exceptions are logged with level "info" instead of
"error". This suppresses some rather boring messages in the default
log level.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/565
This is the documented value, but for unknown reasons, "info" was
really the default.
This was never noticed because there are only very few "info" level
messages.
If the decoder finishes decoding the current song between the two
IsIdle() checks, MPD stops playback instead of starting the decoder
for the next song.
This is usually not visible problem, because the main thread restarts
it via playlist::ResumePlayback(), but that way it, ignores "single"
mode.
As a workaround, this commit adds another "queued" check which
re-enters the player loop and checks again whether to start the
decoder.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/556
The "queued" flag can only possibly be set if the decoder is still
decoding the current song or if the decoder is stopped. This is also
what the following assert() checks. This check was not necessary.
If a read error occurs, it is very unlikely that the InputStream will
ever recover. Removing the code removes some code complexity which
just isn't worth it. And it allows supporting multiple readers for
one buffer.
ALSA is just one out of many output plugins, and detailed plugin
documentation should only live in the user manual, without having
duplicates in the (brief) manpage.
Also move "mixer_type" to the "optional audio output parameters"
section; it is a generic option, not specific to ALSA.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/552
On Windows, we keep using our own implementations, because GCC
implements std::mutex and std::condition_variable with pthread
emulation, which is not a good choice.
Commit b3a458338a added a LocateUri()
call to several playlist commands, which applied InputPlugin URI
scheme verification to playlist URIs. This broke the SoundCloud
playlist plugin which uses "soundcloud://" URIs for which no input
plugin exists.
This commit allows the caller to specify the kind of plugin which
shall be used to verify the URI. Right now, only "input" is
implemented; "storage" uses the "input" verification for now; and
"playlist" has no verification at all (for now).
Closes https://github.com/MusicPlayerDaemon/MPD/issues/528
Expect OnSocketReady() to cancel events. If it returns false, the
SocketMonitor may be destructed already. This fixes a use-after-free
bug in the "httpd" output plugin.
This missing piece probably never really hurt, because
HttpdClient::OnSocketClosed() would be called right after a socket
error, but it's better to be explicit about closing on error.
Fixes:
src/net/IPv4Address.hxx: In member function 'constexpr IPv4Address::operator SocketAddress() const':
src/net/IPv4Address.hxx:171:24: error: a reinterpret_cast is not a constant expression
171 | return SocketAddress((const struct sockaddr *)&address,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/net/IPv6Address.hxx: In member function 'constexpr IPv6Address::operator SocketAddress() const':
src/net/IPv6Address.hxx:138:24: error: a reinterpret_cast is not a constant expression
138 | return SocketAddress((const struct sockaddr *)&address,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Closes https://github.com/MusicPlayerDaemon/MPD/issues/522
Fixes#184.
Semaphores are kernel-managed objects, calling delete_sem() twice is not more
dangerous than calling close() twice on an fd though, it would just return
an error.
The custom_command was run in src/haiku/ and created a file with only resources inside.
Since xres edits the file in-place and meson doesn't like it, we have to run a shell script for now.
Maybe later I'll add proper support in meson.
MPD sometimes uses version numbers like "0.22~git" to mark unreleased
versions. That makes the win32 resource compiler unhappy, because it
expects numbers only.
Since version 0.49.0 the Meson build system has native support for
finding and using the gcrypt library using the `dependency()` function.
`dependency()` has the advantage over `find_library()` as it queries the
required linker flags for proper linking with external libraries, e.g.
libgpg-error.
As the latest released version 1.8.4 of libgcrypt does not
provide a .pc file, using `libgcrypt-config` is the only way to query
the required linker flags.
Unfortunately, there is an issue when cross compiling mpd and the user does not
define `libgcrypt-config` in the cross file. If the user sets the qobuz feature
to `auto` and the target does not have libgcrypt installed, the Meson
build system will falsly assume libgcrypt is available for the target as
it uses the native `libgcrypt-config` on the host and pretend is has
found the library.
Therefore, we still rely on `find_library()` to workaround this buggy
behavior. This way, if qobuz feature detection is set to `auto`, the
feature is disabled in case there is no target libgcrypt available.
Fixes building mpd statically with the qobuz feature enabled. Otherwise
the build fails with undefined references because of the missing libgpg-error
dependency:
```
/sysroot/usr/lib/libgcrypt.a(libgcrypt_la-visibility.o): In function `gcry_strerror':
visibility.c:(.text+0x14): undefined reference to `gpg_strerror'
```
Meson 0.49.0 adds native support for `libgcrypt-config` which is
necessary for detecting libgcrypt dependencies, as the latest
version 1.8.4 of libgcrypt does not provide a .pc file.
using the device "default" brings this plugin into line with the AlsaOutputPlugin; and a sample rate of 48kHz is more widely used as a native default for modern hardware than 44.1kHz
Also fixes an inconsistency between the docs and code.
This is a guide for those who wish to hack on the MPD source code. MPD is an open project, and we are always happy about contributions. So far, more than 150 people have contributed patches. This document is work in progress. Most of it may be incomplete yet. Please help!
This is a guide for those who wish to hack on the MPD source code. MPD is an open project, and we are always happy about contributions. So far, more than 150 people have contributed patches. This document is work in progress. Most of it may be incomplete yet. Please help!
Code Style
Code Style
==========
**********
* indent with tabs (width 8)
* indent with tabs (width 8)
* don't write CPP when you can write C++: use inline functions and constexpr instead of macros
* don't write CPP when you can write C++: use inline functions and constexpr instead of macros
* comment your code, document your APIs
* comment your code, document your APIs
* the code should be C++14 compliant, and must compile with :program:`GCC`6.0 and :program:`clang`3.4
* the code should be C++17 compliant, and must compile with :program:`GCC`8 and :program:`clang`5
* report error conditions with C++ exceptions, preferable derived from :envvar:`std::runtime_error`
* all code must be exception-safe
* all code must be exception-safe
* classes and functions names use CamelCase; variables are lower-case with words separated by underscore
* classes and functions names use CamelCase; variables are lower-case with words separated by underscore
Some example code:
Some example code:
~~~~~~~~~~~~~~~~~~
..code-block::c
..code-block::c
int
Foo(constchar*abc,intxyz)
Foo(constchar*abc,intxyz)
{
{
if(abc==nullptr){
if(abc==nullptr){
@@ -32,8 +31,58 @@ Some example code:
returnxyz;
returnxyz;
}
}
Error handling
==============
If an error occurs, throw a C++ exception, preferably derived from
:code:`std::runtime_error`. The function's API documentation should
mention that. If a function cannot throw exceptions, add
:code:`noexcept` to its prototype.
Some parts of MPD use callbacks to report completion; the handler
classes usually have an "error" callback which receives a
:code:`std::exception_ptr`
(e.g. :code:`BufferedSocket::OnSocketError()`). Wrapping errors in
:code:`std::exception_ptr` allows propagating details about the error
across thread boundaries to the entity which is interested in handling
it (e.g. giving the MPD client details about an I/O error caught by
the decoder thread).
Out-of-memory errors (i.e. :code:`std::bad_alloc`) do not need to be
handled. Some operating systems such as Linux do not report
out-of-memory to userspace, and instead kill a process to recover.
Even if we know we are out of memory, there is little we can do except
for aborting the process quickly. Any other attempts to give back
memory may cause page faults on the way which make the situation
worse.
Error conditions which are caused by a bug do not need to be handled
at runtime; instead, use :code:`assert()` to detect them in debug
builds.
git Branches
************
There are two active branches in the git repository:
- the "unstable" branch called ``master`` where new features are
merged. This will become the next major release eventually.
- the "stable" branch (currently called ``v0.22.x``) where only bug
fixes are merged.
Once :program:`MPD` 0.23 is released, a new branch called ``v0.23.x``
will be created for 0.23 bug-fix releases; after that, ``v0.22.x``
will eventually cease to be maintained.
After bug fixes have been added to the "stable" branch, it will be
merged into ``master``. This ensures that all known bugs are fixed in
@@ -59,7 +108,7 @@ possible, to be sure that you don't break any disabled code.
Don't mix several changes in one single patch. Create a separate patch for every change. Tools like :program:`stgit` help you with that. This way, we can review your patches more easily, and we can pick the patches we like most first.
Don't mix several changes in one single patch. Create a separate patch for every change. Tools like :program:`stgit` help you with that. This way, we can review your patches more easily, and we can pick the patches we like most first.
Basic stgit usage
Basic stgit usage
-----------------
=================
stgit allows you to create a set of patches and refine all of them: you can go back to any patch at any time, and re-edit it (both the code and the commit message). You can reorder patches and insert new patches at any position. It encourages creating separate patches for tiny changes.
stgit allows you to create a set of patches and refine all of them: you can go back to any patch at any time, and re-edit it (both the code and the commit message). You can reorder patches and insert new patches at any position. It encourages creating separate patches for tiny changes.
@@ -94,35 +143,7 @@ When the whole patch series is finished, convert stgit patches to git commits:
stg commit
stg commit
Submitting Patches
Submitting Patches
==================
******************
Send your patches to the mailing list:
Submit pull requests on GitHub:
Email: `mpd-devel <mpd-devel@musicpd.org>`_
https://github.com/MusicPlayerDaemon/MPD/pulls
:program:`git pull` requests are preferred.
Development Tools
=================
Clang Static Analyzer
---------------------
The `static analyzer <http://clang-analyzer.llvm.org/>`_ is a tool that helps find bugs. To run it on the MPD code base, install LLVM and clang. configure MPD to use clang:
MPD is a daemon for playing music. Music is played through the configured audio output(s) (which are generally local, but can be remote). The daemon stores info about all available music, and this info can be easily searched and retrieved. Player control, info retrieval, and playlist management can all be managed remotely.
MPD searches for a config file in ``$XDG_CONFIG_HOME/mpd/mpd.conf``
then ``~/.mpdconf`` then ``~/.mpd/mpd.conf`` then ``/etc/mpd.conf`` or uses ``CONF_FILE``.
Read more about MPD at http://www.musicpd.org/
OPTIONS
-------
..program:: mpd
..option:: --help
Output a brief help message.
..option:: --kill
Kill the currently running mpd session. The pid_file parameter must be specified in the config file for this to work.
..option:: --no-config
Don't read from the configuration file.
..option:: --no-daemon
Don't detach from console.
..option:: --stderr
Print messages to stderr.
..option:: --verbose
Verbose logging.
..option:: --version
Print version information.
FILES
-----
:file:`$XDG_CONFIG_HOME/mpd/mpd.conf`
User configuration file (usually :file:`~/.config/mpd/mpd.conf`).
:file:`/etc/mpd.conf`
Global configuration file.
SEE ALSO
--------
:manpage:`mpd.conf(5)`, :manpage:`mpc(1)`
BUGS
----
If you find a bug, please report it at https://github.com/MusicPlayerDaemon/MPD/issues/
An experimental Android build is available on Google Play. After installing and launching it, :program:`MPD` will scan the music in your Music directory and you can control it as usual with a :program:`MPD` client.
An experimental Android build is available on Google Play. After installing and launching it, :program:`MPD` will scan the music in your Music directory and you can control it as usual with a :program:`MPD` client.
If you need to tweak the configuration, you can create a file called:file:`mpd.conf` on the data partition (the directory which is returned by Android's :dfn:`getExternalStorageDirectory()` API function).
If you need to tweak the configuration, you can create a file called
:file:`mpd.conf` in MPD's data directory on the external storage
@@ -84,14 +89,16 @@ For example, the following installs a fairly complete list of build dependencies
libpulse-dev libshout3-dev \
libpulse-dev libshout3-dev \
libsndio-dev \
libsndio-dev \
libmpdclient-dev \
libmpdclient-dev \
libnfs-dev libsmbclient-dev \
libnfs-dev \
libupnp-dev \
libupnp-dev \
libavahi-client-dev \
libavahi-client-dev \
libsqlite3-dev \
libsqlite3-dev \
libsystemd-dev \
libsystemd-dev \
libgtest-dev \
libgtest-dev \
libboost-dev \
libboost-dev \
libicu-dev
libicu-dev \
libchromaprint-dev \
libgcrypt20-dev
Now configure the source tree:
Now configure the source tree:
@@ -106,6 +113,19 @@ The following command shows a list of compile-time options:
meson configure output/release
meson configure output/release
NB: Check the sysconfdir setting to determine where mpd will look for mpd.conf; if you expect mpd to look for /etc/mpd.conf the sysconfdir must be '/etc' (i.e., not 'etc' which will result in mpd looking for /usr/local/etc/mpd.conf):
..code-block::none
meson configure output/release |grep sysconfdir
If this is not /etc (or another path you wish to specify):
:envvar:`SDK_PATH` is the absolute path where you installed the
:envvar:`SDK_PATH` is the absolute path where you installed the
@@ -183,47 +226,6 @@ ABI is the Android ABI to be built, e.g. ":code:`arm64-v8a`".
This downloads various library sources, and then configures and builds :program:`MPD`.
This downloads various library sources, and then configures and builds :program:`MPD`.
systemd socket activation
-------------------------
Using systemd, you can launch :program:`MPD` on demand when the first client attempts to connect.
:program:`MPD` comes with two systemd unit files:a "service" unit and
a "socket" unit. These will be installed to the directory specified
with :code:`-Dsystemd_system_unit_dir=...`,
e.g. :file:`/lib/systemd/system`.
To enable socket activation, type:
..code-block::none
systemctl enable mpd.socket
systemctl start mpd.socket
In this configuration, :program:`MPD` will ignore the :ref:`listener
settings <listeners>` (``bind_to_address`` and ``port``).
systemd user unit
-----------------
You can launch :program:`MPD` as a systemd user unit. These will be
installed to the directory specified with
:code:`-Dsystemd_user_unit_dir=...`,
e.g. :file:`/usr/lib/systemd/user` or
:file:`$HOME/.local/share/systemd/user`.
Once the user unit is installed, you can start and stop :program:`MPD` like any other service:
..code-block::none
systemctl --user start mpd
To auto-start :program:`MPD` upon login, type:
..code-block::none
systemctl --user enable mpd
Configuration
Configuration
*************
*************
@@ -258,6 +260,13 @@ another file; the given file name is relative to the current file:
include "other.conf"
include "other.conf"
You can use :code:`include_optional` instead if you want the included file
to be optional; the directive will be ignored if the file does not exist:
..code-block::none
include_optional "may_not_exist.conf"
Configuring the music directory
Configuring the music directory
-------------------------------
-------------------------------
@@ -294,7 +303,7 @@ Configuring neighbor plugins
----------------------------
----------------------------
All neighbor plugins are disabled by default to avoid unwanted
All neighbor plugins are disabled by default to avoid unwanted
overhead. To enable (and configure) a plugin, add a :code:`neighbor`
overhead. To enable (and configure) a plugin, add a :code:`neighbors`
block to :file:`mpd.conf`:
block to :file:`mpd.conf`:
..code-block::none
..code-block::none
@@ -334,6 +343,44 @@ The following table lists the input options valid for all plugins:
More information can be found in the :ref:`input_plugins` reference.
More information can be found in the :ref:`input_plugins` reference.
.._input_cache:
Configuring the Input Cache
^^^^^^^^^^^^^^^^^^^^^^^^^^^
The input cache prefetches queued song files before they are going to
be played. This has several advantages:
- risk of buffer underruns during playback is reduced because this
decouples playback from disk (or network) I/O
- bulk transfers may be faster and more energy efficient than loading
small chunks on-the-fly
- by prefetching several songs at a time, the hard disk can spin down
for longer periods of time
This comes at a cost:
- memory usage
- bulk transfers may reduce the performance of other applications
which also want to access the disk (if the kernel's I/O scheduler
isn't doing its job properly)
To enable the input cache, add an ``input_cache`` block to the
configuration file:
..code-block::none
input_cache {
size "1 GB"
}
This allocates a cache of 1 GB. If the cache grows larger than that,
older files will be evicted.
You can flush the cache at any time by sending ``SIGHUP`` to the
:program:`MPD` process, see :ref:`signals`.
Configuring decoder plugins
Configuring decoder plugins
---------------------------
---------------------------
@@ -365,10 +412,14 @@ More information can be found in the :ref:`decoder_plugins` reference.
Configuring encoder plugins
Configuring encoder plugins
---------------------------
---------------------------
Encoders are used by some of the output plugins (such as shout). The encoder settings are included in the audio_output section.
Encoders are used by some of the output plugins (such as shout). The
encoder settings are included in the ``audio_output`` section, see :ref:`config_audio_output`.
More information can be found in the :ref:`encoder_plugins` reference.
More information can be found in the :ref:`encoder_plugins` reference.
.._config_audio_output:
Configuring audio outputs
Configuring audio outputs
-------------------------
-------------------------
@@ -398,15 +449,10 @@ The following table lists the audio_output options valid for all plugins:
- The name of the plugin
- The name of the plugin
* - **name**
* - **name**
- The name of the audio output. It is visible to the client. Some plugins also use it internally, e.g. as a name registered in the PULSE server.
- The name of the audio output. It is visible to the client. Some plugins also use it internally, e.g. as a name registered in the PULSE server.
* - **format**
* - **format samplerate:bits:channels**
- Always open the audio output with the specified audio format samplerate:bits:channels), regardless of the format of the input file. This is optional for most plugins.
- Always open the audio output with the specified audio format, regardless of the format of the input file. This is optional for most plugins.
See :ref:`audio_output_format` for a detailed description of the value.
Any of the three attributes may be an asterisk to specify that this attribute should not be enforced, example: 48000:16:*. *:*:* is equal to not having a format specification.
* - **enabled yes|no**
The following values are valid for bits: 8 (signed 8 bit integer samples), 16, 24 (signed 24 bit integer samples padded to 32 bit), 32 (signed 32 bit integer samples), f (32 bit floating point, -1.0 to 1.0), "dsd" means DSD (Direct Stream Digital). For DSD, there are special cases such as "dsd64", which allows you to omit the sample rate (e.g. dsd512:2 for stereo DSD512, i.e. 22.5792 MHz).
The sample rate is special for DSD: :program:`MPD` counts the number of bytes, not bits. Thus, a DSD "bit" rate of 22.5792 MHz (DSD512) is 2822400 from :program:`MPD`'s point of view (44100*512/8).
* - **enabed yes|no**
- Specifies whether this audio output is enabled when :program:`MPD` is started. By default, all audio outputs are enabled. This is just the default setting when there is no state file; with a state file, the previous state is restored.
- Specifies whether this audio output is enabled when :program:`MPD` is started. By default, all audio outputs are enabled. This is just the default setting when there is no state file; with a state file, the previous state is restored.
* - **tags yes|no**
* - **tags yes|no**
- If set to no, then :program:`MPD` will not send tags to this output. This is only useful for output plugins that can receive tags, for example the httpd output plugin.
- If set to no, then :program:`MPD` will not send tags to this output. This is only useful for output plugins that can receive tags, for example the httpd output plugin.
@@ -418,9 +464,23 @@ The following table lists the audio_output options valid for all plugins:
:ref:`oss_plugin` and PulseAudio :ref:`pulse_plugin`), the
:ref:`oss_plugin` and PulseAudio :ref:`pulse_plugin`), the
software mixer, the ":samp:`null`" mixer (allows setting the
software mixer, the ":samp:`null`" mixer (allows setting the
volume, but with no effect; this can be used as a trick to
volume, but with no effect; this can be used as a trick to
implement an external mixer :ref:`external_mixer`) or no mixer
implement an external mixer, see:ref:`external_mixer`) or no mixer
(:samp:`none`). By default, the hardware mixer is used for
(:samp:`none`). By default, the hardware mixer is used for
devices which support it, and none for the others.
devices which support it, and none for the others.
* - **replay_gain_handler software|mixer|none**
- Specifies how :ref:`replay_gain` is applied. The default is
``software``, which uses an internal software volume control.
``mixer`` uses the configured (hardware) mixer control.
``none`` disables replay gain on this audio output.
* - **filters "name,...**"
- The specified configured filters are instantiated in the given
order. Each filter name refers to a ``filter`` block, see
:ref:`config_filter`.
More information can be found in the :ref:`output_plugins` reference.
.._config_filter:
Configuring filters
Configuring filters
-------------------
-------------------
@@ -436,6 +496,9 @@ To configure a filter, add a :code:`filter` block to :file:`mpd.conf`:
name "software volume"
name "software volume"
}
}
Configured filters may then be added to the ``filters`` setting of an
``audio_output`` section, see :ref:`config_audio_output`.
The following table lists the filter options valid for all plugins:
The following table lists the filter options valid for all plugins:
..list-table::
..list-table::
@@ -449,6 +512,9 @@ The following table lists the filter options valid for all plugins:
* - **name**
* - **name**
- The name of the filter
- The name of the filter
More information can be found in the :ref:`filter_plugins` reference.
Configuring playlist plugins
Configuring playlist plugins
----------------------------
----------------------------
@@ -474,10 +540,15 @@ The following table lists the playlist_plugin options valid for all plugins:
* - Name
* - Name
- Description
- Description
* - **plugin**
* - **name**
- The name of the plugin
- The name of the plugin
* - **enabled yes|no**
* - **enabled yes|no**
- Allows you to disable a playlist plugin without recompiling. By default, all plugins are enabled.
- Allows you to disable a playlist plugin without recompiling. By default, all plugins are enabled.
* - **as_directory yes|no**
- With this option, a playlist file of this type is parsed during
database update and converted to a virtual directory, allowing
MPD clients to access individual entries. By default, this is
only enabled for the :ref:`cue plugin <cue_playlist>`.
More information can be found in the :ref:`playlist_plugins`
More information can be found in the :ref:`playlist_plugins`
reference.
reference.
@@ -485,26 +556,133 @@ reference.
Audio Format Settings
Audio Format Settings
---------------------
---------------------
Global Audio Format
.._audio_output_format:
~~~~~~~~~~~~~~~~~~~
The setting audio_output_format forces :program:`MPD` to use one audio format for all outputs. Doing that is usually not a good idea. The values are the same as in format in the audio_output section.
Global Audio Format
^^^^^^^^^^^^^^^^^^^
The setting ``audio_output_format`` forces :program:`MPD` to use one
audio format for all outputs. Doing that is usually not a good idea.
The value is specified as ``samplerate:bits:channels``.
Any of the three attributes may be an asterisk to specify that this
attribute should not be enforced, example: ``48000:16:*``.
``*:*:*`` is equal to not having a format specification.
The following values are valid for bits: ``8`` (signed 8 bit integer
samples), ``16``, ``24`` (signed 24 bit integer samples padded to 32
bit), ``32`` (signed 32 bit integer samples), ``f`` (32 bit floating
point, -1.0 to 1.0), ``dsd`` means DSD (Direct Stream Digital). For
DSD, there are special cases such as ``dsd64``, which allows you to
omit the sample rate (e.g. ``dsd512:2`` for stereo DSD512,
i.e. 22.5792 MHz).
The sample rate is special for DSD: :program:`MPD` counts the number
of bytes, not bits. Thus, a DSD "bit" rate of 22.5792 MHz (DSD512) is
2822400 from :program:`MPD`'s point of view (44100*512/8).
Resampler
Resampler
~~~~~~~~~
^^^^^^^^^
Sometimes, music needs to be resampled before it can be played; for example, CDs use a sample rate of 44,100 Hz while many cheap audio chips can only handle 48,000 Hz. Resampling reduces the quality and consumes a lot of CPU. There are different options, some of them optimized for high quality and others for low CPU usage, but you can't have both at the same time. Often, the resampler is the component that is responsible for most of :program:`MPD`'s CPU usage. Since :program:`MPD` comes with high quality defaults, it may appear that :program:`MPD` consumes more CPU than other software.
Sometimes, music needs to be resampled before it can be played; for example, CDs use a sample rate of 44,100 Hz while many cheap audio chips can only handle 48,000 Hz. Resampling reduces the quality and consumes a lot of CPU. There are different options, some of them optimized for high quality and others for low CPU usage, but you can't have both at the same time. Often, the resampler is the component that is responsible for most of :program:`MPD`'s CPU usage. Since :program:`MPD` comes with high quality defaults, it may appear that :program:`MPD` consumes more CPU than other software.
Check the :ref:`resampler_plugins` reference for a list of resamplers
Check the :ref:`resampler_plugins` reference for a list of resamplers
and how to configure them.
and how to configure them.
Volume Normalization Settings
-----------------------------
.._replay_gain:
Replay Gain
^^^^^^^^^^^
The setting ``replaygain`` specifies whether MPD shall adjust the
Setting this to ``album`` will adjust volume using the album's
ReplayGain tags, while setting it to ``track`` will adjust it using
the "track" ReplayGain tags. ``auto`` uses the track ReplayGain tags
if random play is activated otherwise the album ReplayGain
tags.
If ReplayGain is enabled, then the setting ``replaygain_preamp`` is
set to a value (in dB) between ``-15`` and ``15``. This is the gain
applied to songs with ReplayGain tags.
On songs without ReplayGain tags, the setting
``replaygain_missing_preamp`` is used instead. If this setting is not
configured, then no ReplayGain is applied to such songs, and they will
appear too loud.
ReplayGain is usually implemented with a software volume filter (which
prevents `Bit-perfect playback`_). To use a hardware mixer, set
``replay_gain_handler`` to ``mixer`` in the ``audio_output`` section
(see :ref:`config_audio_output` for details).
Simple Volume Normalization
^^^^^^^^^^^^^^^^^^^^^^^^^^^
MPD implements a very simple volume normalization method which can be
enabled by setting ``volume_normalization`` to ``yes``. It supports
16 bit PCM only.
.._crossfading:
Cross-Fading
------------
If ``crossfade`` is set to a positive number, then adjacent songs are
cross-faded by this number of seconds. This is a run-time setting
:ref:`which can be controlled by clients <command_crossfade>`,
e.g. with :program:`mpc`::
mpc crossfade 10
mpc crossfade 0
Zero means cross-fading is disabled.
Cross-fading is only possible if both songs have the same audio
format. At the cost of quality loss and higher CPU usage, you can
make sure this is always given by configuring
:ref:`audio_output_format`.
.._mixramp:
MixRamp
^^^^^^^
MixRamp tags describe the loudness levels at start and end of a song
and can be used by MPD to find the best time to begin cross-fading.
MPD enables MixRamp if:
- Cross-fade is enabled
-:ref:`mixrampdelay <command_mixrampdelay>` is set to a positive
value, e.g.::
mpc mixrampdelay 1
-:ref:`mixrampdb <command_mixrampdb>` is set to a reasonable value,
e.g.::
mpc mixrampdb -17
- both songs have MixRamp tags
- both songs have the same audio format (or :ref:`audio_output_format`
is configured)
The `MixRamp <http://sourceforge.net/projects/mixramp>`__ tool can be
used to add MixRamp tags to your song files.
Client Connections
Client Connections
------------------
------------------
.._listeners:
.._listeners:
Listeners
Listeners
~~~~~~~~~
^^^^^^^^^
The setting :code:`bind_to_address` specifies which addresses
The setting :code:`bind_to_address` specifies which addresses
:program:`MPD` listens on for connections from clients. It can be
:program:`MPD` listens on for connections from clients. It can be
@@ -547,7 +725,7 @@ used.
Permissions and Passwords
Permissions and Passwords
~~~~~~~~~~~~~~~~~~~~~~~~~
^^^^^^^^^^^^^^^^^^^^^^^^^
By default, all clients are unauthenticated and have a full set of permissions. This can be restricted with the settings :code:`default_permissions` and :code:`password`.
By default, all clients are unauthenticated and have a full set of permissions. This can be restricted with the settings :code:`default_permissions` and :code:`password`.
@@ -563,13 +741,20 @@ By default, all clients are unauthenticated and have a full set of permissions.
- Allows reading of the database, displaying the current playlist, and current status of :program:`MPD`.
- Allows reading of the database, displaying the current playlist, and current status of :program:`MPD`.
* - **add**
* - **add**
- Allows adding songs and loading playlists.
- Allows adding songs and loading playlists.
* - **player**
- Allows any player and queue manipulation (start/pause/stop
playback etc.).
* - **control**
* - **control**
- Allows all other player and playlist manipulations.
- Allows all other player and playlist manipulations.
* - **admin**
* - **admin**
- Allows database updates and allows shutting down :program:`MPD`.
- Allows manipulating outputs, stickers and partitions,
mounting/unmounting storage and shutting down :program:`MPD`.
:code:`local_permissions` may be used to assign other permissions to clients connecting on a local socket.
:code:`local_permissions` may be used to assign other permissions to clients connecting on a local socket.
:code:`host_permissions` may be used to assign permissions to clients
with a certain IP address.
:code:`password` allows the client to send a password to gain other permissions. This option may be specified multiple times with different passwords.
:code:`password` allows the client to send a password to gain other permissions. This option may be specified multiple times with different passwords.
Note that the :code:`password` option is not secure: passwords are sent in clear-text over the connection, and the client cannot verify the server's identity.
Note that the :code:`password` option is not secure: passwords are sent in clear-text over the connection, and the client cannot verify the server's identity.
Section :ref:`tags` contains a list of supported tags.
Section :ref:`tags` contains a list of supported tags.
The State File
The State File
~~~~~~~~~~~~~~
^^^^^^^^^^^^^^
The state file is a file where :program:`MPD` saves and restores its state (play queue, playback position etc.) to keep it persistent across restarts and reboots. It is an optional setting.
The state file is a file where :program:`MPD` saves and restores its state (play queue, playback position etc.) to keep it persistent across restarts and reboots. It is an optional setting.
@@ -626,9 +813,11 @@ The State File
- Specify the state file location. The parent directory must be writable by the :program:`MPD` user (+wx).
- Specify the state file location. The parent directory must be writable by the :program:`MPD` user (+wx).
* - **state_file_interval SECONDS**
* - **state_file_interval SECONDS**
- Auto-save the state file this number of seconds after each state change. Defaults to 120 (2 minutes).
- Auto-save the state file this number of seconds after each state change. Defaults to 120 (2 minutes).
* - **restore_paused yes|no**
- If set to :samp:`yes`, then :program:`MPD` is put into pause mode instead of starting playback after startup. Default is :samp:`no`.
The Sticker Database
The Sticker Database
~~~~~~~~~~~~~~~~~~~~
^^^^^^^^^^^^^^^^^^^^
"Stickers" are pieces of information attached to songs. Some clients
"Stickers" are pieces of information attached to songs. Some clients
use them to store ratings and other volatile data. This feature
use them to store ratings and other volatile data. This feature
These settings are various limitations to prevent :program:`MPD` from using too many resources (denial of service).
These settings are various limitations to prevent :program:`MPD` from using too many resources (denial of service).
@@ -658,7 +847,7 @@ These settings are various limitations to prevent :program:`MPD` from using too
* - **connection_timeout SECONDS**
* - **connection_timeout SECONDS**
- If a client does not send any new data in this time period, the connection is closed. Clients waiting in "idle" mode are excluded from this. Default is 60.
- If a client does not send any new data in this time period, the connection is closed. Clients waiting in "idle" mode are excluded from this. Default is 60.
* - **max_connections NUMBER**
* - **max_connections NUMBER**
- This specifies the maximum number of clients that can be connected to :program:`MPD` at the same time. Default is 5.
- This specifies the maximum number of clients that can be connected to :program:`MPD` at the same time. Default is 100.
* - **max_playlist_length NUMBER**
* - **max_playlist_length NUMBER**
- The maximum number of songs that can be in the playlist. Default is 16384.
- The maximum number of songs that can be in the playlist. Default is 16384.
* - **max_command_list_size KBYTES**
* - **max_command_list_size KBYTES**
@@ -667,7 +856,7 @@ These settings are various limitations to prevent :program:`MPD` from using too
- The maximum size of the output buffer to a client (maximum response size). Default is 8192 (8 MiB).
- The maximum size of the output buffer to a client (maximum response size). Default is 8192 (8 MiB).
Buffer Settings
Buffer Settings
~~~~~~~~~~~~~~~
^^^^^^^^^^^^^^^
Do not change these unless you know what you are doing.
Do not change these unless you know what you are doing.
@@ -677,11 +866,12 @@ Do not change these unless you know what you are doing.
* - Setting
* - Setting
- Description
- Description
* - **audio_buffer_size KBYTES**
* - **audio_buffer_size SIZE**
- Adjust the size of the internal audio buffer. Default is 4096 (4 MiB).
- Adjust the size of the internal audio buffer. Default is
:samp:`4 MB` (4 MiB).
Zeroconf
Zeroconf
~~~~~~~~
^^^^^^^^
If Zeroconf support (`Avahi <http://avahi.org/>`_ or Apple's Bonjour)
If Zeroconf support (`Avahi <http://avahi.org/>`_ or Apple's Bonjour)
was enabled at compile time with :code:`-Dzeroconf=...`,
was enabled at compile time with :code:`-Dzeroconf=...`,
@@ -726,22 +916,24 @@ The :code:`music_directory` setting tells :program:`MPD` to read files from the
The database setting tells :program:`MPD` to pass all database queries on to the :program:`MPD` instance running on the file server (using the proxy plugin).
The database setting tells :program:`MPD` to pass all database queries on to the :program:`MPD` instance running on the file server (using the proxy plugin).
.._realtime:
Real-Time Scheduling
Real-Time Scheduling
--------------------
--------------------
On Linux, :program:`MPD` attempts to configure real-time scheduling for some threads that benefit from it.
On Linux, :program:`MPD` attempts to configure real-time scheduling for some threads that benefit from it.
This is only possible you allow :program:`MPD` to do it. This privilege is controlled by :envvar:`RLIMIT_RTPRIO`:envvar:`RLIMIT_RTTIME`. You can configure this privilege with :command:`ulimit` before launching :program:`MPD`:
This is only possible if you allow :program:`MPD` to do it. This privilege is controlled by :envvar:`RLIMIT_RTPRIO`:envvar:`RLIMIT_RTTIME`. You can configure this privilege with :command:`ulimit` before launching :program:`MPD`:
..code-block::none
..code-block::none
ulimit -HS -r 50; mpd
ulimit -HS -r 40; mpd
Or you can use the :command:`prlimit` program from the util-linux package:
Or you can use the :command:`prlimit` program from the util-linux package:
..code-block::none
..code-block::none
prlimit --rtprio=50 --rttime=unlimited mpd
prlimit --rtprio=40 --rttime=unlimited mpd
The systemd service file shipped with :program:`MPD` comes with this setting.
The systemd service file shipped with :program:`MPD` comes with this setting.
@@ -759,22 +951,107 @@ You can verify whether the real-time scheduler is active with the ps command:
PID TID CLS RTPRIO COMMAND
PID TID CLS RTPRIO COMMAND
16257 16257 TS - mpd
16257 16257 TS - mpd
16257 16258 TS - io
16257 16258 TS - io
16257 16259 FF 50 rtio
16257 16259 FF 40 rtio
16257 16260 TS - player
16257 16260 TS - player
16257 16261 TS - decoder
16257 16261 TS - decoder
16257 16262 FF 50 output:ALSA
16257 16262 FF 40 output:ALSA
16257 16263 IDL 0 update
16257 16263 IDL 0 update
The CLS column shows the CPU scheduler; TS is the normal scheduler; FF and RR are real-time schedulers. In this example, two threads use the real-time scheduler: the output thread and the rtio (real-time I/O) thread; these two are the important ones. The database update thread uses the idle scheduler ("IDL in ps), which only gets CPU when no other process needs it.
The CLS column shows the CPU scheduler; TS is the normal scheduler; FF and RR are real-time schedulers. In this example, two threads use the real-time scheduler: the output thread and the rtio (real-time I/O) thread; these two are the important ones. The database update thread uses the idle scheduler ("IDL in ps), which only gets CPU when no other process needs it.
Note
..note::
~~~~
There is a rumor that real-time scheduling improves audio quality. That is not true. All it does is reduce the probability of skipping (audio buffer xruns) when the computer is under heavy load.
There is a rumor that real-time scheduling improves audio
quality. That is not true. All it does is reduce the probability of
skipping (audio buffer xruns) when the computer is under heavy
load.
Using MPD
Using MPD
*********
*********
Starting and Stopping MPD
-------------------------
The simplest (but not the best) way to start :program:`MPD` is to
simply type::
mpd
This will start :program:`MPD` as a daemon process (which means it
detaches from your terminal and continues to run in background). To
stop it, send ``SIGTERM`` to the process; if you have configured a
``pid_file``, you can use the ``--kill`` option::
mpd --kill
The best way to manage :program:`MPD` processes is to use a service
manager such as :program:`systemd`.
systemd
^^^^^^^
:program:`MPD` ships with :program:`systemd` service units.
If you have installed :program:`MPD` with your operating system's
package manager, these are probably preinstalled, so you can start and
stop :program:`MPD` this way (like any other service)::
systemctl start mpd
systemctl stop mpd
systemd socket activation
^^^^^^^^^^^^^^^^^^^^^^^^^
Using systemd, you can launch :program:`MPD` on demand when the first client attempts to connect.
:program:`MPD` comes with two systemd unit files:a "service" unit and
a "socket" unit. These will be installed to the directory specified
with :code:`-Dsystemd_system_unit_dir=...`,
e.g. :file:`/lib/systemd/system`.
To enable socket activation, type:
..code-block::none
systemctl enable mpd.socket
systemctl start mpd.socket
In this configuration, :program:`MPD` will ignore the :ref:`listener
settings <listeners>` (``bind_to_address`` and ``port``).
systemd user unit
^^^^^^^^^^^^^^^^^
You can launch :program:`MPD` as a systemd user unit. These will be
installed to the directory specified with
:code:`-Dsystemd_user_unit_dir=...`,
e.g. :file:`/usr/lib/systemd/user` or
:file:`$HOME/.local/share/systemd/user`.
Once the user unit is installed, you can start and stop :program:`MPD` like any other service:
..code-block::none
systemctl --user start mpd
To auto-start :program:`MPD` upon login, type:
..code-block::none
systemctl --user enable mpd
.._signals:
Signals
-------
:program:`MPD` understands the following UNIX signals:
-``SIGTERM``, ``SIGINT``: shut down MPD
-``SIGHUP``: reopen log files (send this after log rotation) and
flush caches (see :ref:`input_cache`)
The client
The client
----------
----------
@@ -795,10 +1072,22 @@ The "music directory" is where you store your music files. :program:`MPD` stores
Depending on the size of your music collection and the speed of the storage, this can take a while.
Depending on the size of your music collection and the speed of the storage, this can take a while.
To exclude a file from the update, create a file called:file:`.mpdignore` in its parent directory. Each line of that file may contain a list of shell wildcards. Matching files in the current directory and all subdirectories are excluded.
To exclude a file from the update, create a file called
:file:`.mpdignore` in its parent directory. Each line of that file
may contain a list of shell wildcards. Matching files (or
directories) in the current directory and all subdirectories are
excluded. Example::
*.opus
99*
Subject to pattern matching is the file/directory name. It is (not
yet) possible to match nested path names, e.g. something like
``foo/*.flac`` is not possible.
Mounting other storages into the music directory
Mounting other storages into the music directory
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:program:`MPD` has various storage plugins of which multiple instances can be "mounted" into the music directory. This way, you can use local music, file servers and USB sticks at the same time. Example:
:program:`MPD` has various storage plugins of which multiple instances can be "mounted" into the music directory. This way, you can use local music, file servers and USB sticks at the same time. Example:
@@ -835,6 +1124,15 @@ See :ref:`tags` for a list of supported tags.
The :ref:`metadata_to_use <metadata_to_use>` setting can be used to
The :ref:`metadata_to_use <metadata_to_use>` setting can be used to
enable or disable certain tags.
enable or disable certain tags.
Note that :program:`MPD` may not necessarily read metadata itself,
instead relying on data reported by the decoder that was used to read
a file. For example, this is the case for the FFmpeg decoder: both
:program:`MPD` and FFmpeg need to support a given metadata format in
order for metadata to be picked up correctly.
Only if a decoder does not have metadata support will :program:`MPD`
attempt to parse a song's metadata itself.
The queue
The queue
---------
---------
@@ -866,7 +1164,7 @@ To verify if :program:`MPD` converts the audio format, enable verbose logging, a
..code-block::none
..code-block::none
decoder: audio_format=44100:24:2, seekable=true
decoder: audio_format=44100:24:2, seekable=true
output: opened plugin=alsa name="An ALSA output"audio_format=44100:16:2
output: opened plugin=alsa name="An ALSA output"audio_format=44100:16:2
output: converting from 44100:24:2
output: converting from 44100:24:2
This example shows that a 24 bit file is being played, but the sound chip cannot play 24 bit. It falls back to 16 bit, discarding 8 bit.
This example shows that a 24 bit file is being played, but the sound chip cannot play 24 bit. It falls back to 16 bit, discarding 8 bit.
@@ -892,16 +1190,25 @@ Check list for bit-perfect playback:
* Disable sound processing inside ALSA by configuring a "hardware"
* Disable sound processing inside ALSA by configuring a "hardware"
device (:samp:`hw:0,0` or similar).
device (:samp:`hw:0,0` or similar).
* Don't use software volume (setting :code:`mixer_type`).
* Don't use software volume (setting :code:`mixer_type`).
* Don't use :ref:`replay_gain`.
* Don't force :program:`MPD` to use a specific audio format (settings
* Don't force :program:`MPD` to use a specific audio format (settings
* Verify that you are really doing bit-perfect playback using :program:`MPD`'s verbose log and :file:`/proc/asound/card*/pcm*p/sub*/hw_params`. Some DACs can also indicate the audio format.
* Verify that you are really doing bit-perfect playback using :program:`MPD`'s verbose log and :file:`/proc/asound/card*/pcm*p/sub*/hw_params`. Some DACs can also indicate the audio format.
.._dsd:
Direct Stream Digital (DSD)
Direct Stream Digital (DSD)
---------------------------
---------------------------
DSD (`Direct Stream Digital<https://en.wikipedia.org/wiki/Direct_Stream_Digital>`_) is a digital format that stores audio as a sequence of single-bit values at a very high sampling rate.
DSD (`Direct Stream Digital
<https://en.wikipedia.org/wiki/Direct_Stream_Digital>`_) is a digital
format that stores audio as a sequence of single-bit values at a very
high sampling rate. It is the sample format used on `Super Audio CDs
<https://en.wikipedia.org/wiki/Super_Audio_CD>`_.
:program:`MPD` understands the file formats dff and dsf. There are three ways to play back DSD:
:program:`MPD` understands the file formats :ref:`DSDIFF
<decoder_dsdiff>` and :ref:`DSF <decoder_dsf>`. There are three ways
to play back DSD:
* Native DSD playback. Requires ALSA 1.0.27.1 or later, a sound driver/chip that supports DSD and of course a DAC that supports DSD.
* Native DSD playback. Requires ALSA 1.0.27.1 or later, a sound driver/chip that supports DSD and of course a DAC that supports DSD.
@@ -914,6 +1221,22 @@ is no way for :program:`MPD` to find out whether the DAC supports
it. DSD to PCM conversion is the fallback if DSD cannot be used
it. DSD to PCM conversion is the fallback if DSD cannot be used
directly.
directly.
ICY-MetaData
------------
Some MP3 streams send information about the current song with a
@@ -938,47 +1261,79 @@ Sometimes, it is helpful to run :program:`MPD` in a terminal and follow what hap
..code-block::none
..code-block::none
mpd --stdout --no-daemon --verbose
mpd --stderr --no-daemon --verbose
Support
Support
-------
-------
Getting Help
Getting Help
~~~~~~~~~~~~
^^^^^^^^^^^^
The :program:`MPD` project runs a `forum <https://forum.musicpd.org/>`_ and an IRC channel (#mpd on Freenode) for requesting help. Visit the MPD help page for details on how to get help.
The :program:`MPD` project runs a `forum <https://forum.musicpd.org/>`_ and an IRC channel (#mpd on Libera.Chat) for requesting help. Visit the MPD help page for details on how to get help.
Common Problems
Common Problems
~~~~~~~~~~~~~~~
^^^^^^^^^^^^^^^
1. Database
Startup
^^^^^^^^^^^
"""""""
Question: I can't see my music in the MPD database!
This happens on Linux when :file:`/proc/sys/net/ipv6/bindv6only` is
disabled. MPD first binds to IPv6, and this automatically binds to
IPv4 as well; after that, MPD binds to IPv4, but that fails. You can
safely ignore this, because MPD works on both IPv4 and IPv6.
Database
""""""""
I can't see my music in the MPD database
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Check your :code:`music_directory` setting.
* Check your :code:`music_directory` setting.
* Does the MPD user have read permission on all music files, and read+execute permission on all music directories (and all of their parent directories)?
* Does the MPD user have read permission on all music files, and read+execute permission on all music directories (and all of their parent directories)?
* Did you update the database? (mpc update)
* Did you update the database? (mpc update)
* Did you enable all relevant decoder plugins at compile time? :command:`mpd --version` will tell you.
* Did you enable all relevant decoder plugins at compile time? :command:`mpd --version` will tell you.
Question: MPD doesn't read ID3 tags!
MPD doesn't read ID3 tags!
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
~~~~~~~~~~~~~~~~~~~~~~~~~~
* You probably compiled :program:`MPD` without libid3tag. :command:`mpd --version` will tell you.
* You probably compiled :program:`MPD` without libid3tag. :command:`mpd --version` will tell you.
2.Playback
Playback
^^^^^^^^^^^
""""""""
Question: I can't hear music on my client!
I can't hear music on my client
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* That problem usually follows a misunderstanding of the nature of :program:`MPD`. :program:`MPD` is a remote-controlled music player, not a music distribution system. Usually, the speakers are connected to the box where :program:`MPD` runs, and the :program:`MPD` client only sends control commands, but the client does not actually play your music.
* That problem usually follows a misunderstanding of the nature of :program:`MPD`. :program:`MPD` is a remote-controlled music player, not a music distribution system. Usually, the speakers are connected to the box where :program:`MPD` runs, and the :program:`MPD` client only sends control commands, but the client does not actually play your music.
:program:`MPD` has output plugins which allow hearing music on a remote host (such as httpd), but that is not :program:`MPD`'s primary design goal.
:program:`MPD` has output plugins which allow hearing music on a remote host (such as httpd), but that is not :program:`MPD`'s primary design goal.
Question: "Device or resource busy"
Error "Device or resource busy"
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* This ALSA error means that another program uses your sound hardware exclusively. You can stop that program to allow :program:`MPD` to use it.
* This ALSA error means that another program uses your sound hardware exclusively. You can stop that program to allow :program:`MPD` to use it.
@@ -996,8 +1351,36 @@ Your bug report should contain:
* relevant portions of the log file (:option:`--verbose`)
* relevant portions of the log file (:option:`--verbose`)
* be clear about what you expect MPD to do, and what is actually happening
* be clear about what you expect MPD to do, and what is actually happening
.._profiler:
Too Much CPU Usage
^^^^^^^^^^^^^^^^^^
If you believe MPD consumes too much CPU, `write a bug report
<https://github.com/MusicPlayerDaemon/MPD/issues>`_ with a profiling
information.
On Linux, this can be obtained with :program:`perf` (on Debian,
installed the package :file:`linux-perf`), for example::
perf record -p `pidof mpd`
Run this command while MPD consumes much CPU, let it run for a minute
or so, and stop it by pressing ``Ctrl-C``. Then type::
perf report >mpd_perf.txt
Upload the output file to the bug report.
..note::
This requires having debug symbols for MPD and all relevant
libraries. See :ref:`crash` for details.
.._crash:
MPD crashes
MPD crashes
~~~~~~~~~~~
^^^^^^^^^^^
All :program:`MPD` crashes are bugs which must be fixed by a developer, and you should write a bug report. (Many crash bugs are caused by codec libraries used by :program:`MPD`, and then that library must be fixed; but in any case, the :program:`MPD``bug tracker <https://github.com/MusicPlayerDaemon/MPD/issues>`_ is a good place to report it first if you don't know.)
All :program:`MPD` crashes are bugs which must be fixed by a developer, and you should write a bug report. (Many crash bugs are caused by codec libraries used by :program:`MPD`, and then that library must be fixed; but in any case, the :program:`MPD``bug tracker <https://github.com/MusicPlayerDaemon/MPD/issues>`_ is a good place to report it first if you don't know.)
@@ -1018,7 +1401,7 @@ You can extract the backtrace from a core dump, or by running :program:`MPD` in
..code-block::none
..code-block::none
gdb --args mpd --stdout --no-daemon --verbose
gdb --args mpd --stderr --no-daemon --verbose
run
run
As soon as you have reproduced the crash, type ":command:`bt`" on the
As soon as you have reproduced the crash, type ":command:`bt`" on the
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.