Compare commits

..

1088 Commits

Author SHA1 Message Date
Max Kellermann
b7fdff46f2 release v0.23.2 2021-10-22 12:45:45 +02:00
Max Kellermann
e16109330d input/last: clear "uri" in OnCloseTimer()
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
2021-10-22 12:45:18 +02:00
Max Kellermann
72621531e0 protocol/Result: convert to Client method 2021-10-22 11:55:39 +02:00
Max Kellermann
0a48146efc client/Client: pass std::string_view to Write()
Almost all callers have string literal, and the length is known at
compile time.
2021-10-22 11:54:14 +02:00
Max Kellermann
0c4bf12bfd player/CrossFade: fix inverted check and wrong variable
The inverted check was introduced by commit 46d00dd85f, and commit
8ad17d25ef added a check for the wrong variable.  D'oh!

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1303
2021-10-22 11:49:38 +02:00
Max Kellermann
b8e0855ef3 output/pipewire: obey PipeWire's DSD bit order and interleave
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1297
2021-10-21 21:15:16 +02:00
Max Kellermann
6467502b9d output/pipewire: restore SampleFormat::DSD after ToPipeWireAudioFormat() call 2021-10-21 21:15:13 +02:00
Max Kellermann
15b67f20e5 output/pipewire: un-inline ParamChanged() 2021-10-21 20:11:22 +02:00
Max Kellermann
0825179f00 output/pipewire: add local reference variables 2021-10-21 20:02:59 +02:00
Max Kellermann
97211d0aad output/pipewire: rename field "buffer" to "pod_buffer" 2021-10-21 20:02:32 +02:00
Max Kellermann
029c499bfa output/pipewire: use std::fill_n() 2021-10-21 20:01:44 +02:00
Max Kellermann
0ba867ec16 output/pipewire: use MAX_CHANNELS, not SPA_AUDIO_MAX_CHANNELS
MPD supports only 8 channels, so MAX_CHANNELS is enough, the array
doens't need to be SPA_AUDIO_MAX_CHANNELS (which is 64).
2021-10-21 20:01:01 +02:00
Max Kellermann
866d147122 output/pipewire: make field "channels" unsigned 2021-10-21 19:59:48 +02:00
Max Kellermann
32851d1bc7 output/pipewire: DSD support
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1297
2021-10-20 11:39:54 +02:00
Max Kellermann
78257408b4 output/pipewire: report errors from the "state_changed" callback 2021-10-20 11:24:57 +02:00
Max Kellermann
f447b7615e output/pipewire: check pw_stream_connect() errors 2021-10-20 11:24:51 +02:00
Max Kellermann
1f780b7209 output/Thread: log exception details 2021-10-20 11:24:51 +02:00
Max Kellermann
04bf8a6b1a output/pipewire: fix memory leak in SendTag() 2021-10-20 10:16:36 +02:00
Max Kellermann
c4c64854d4 output/pipewire: evaluate errno after libpipewire function calls 2021-10-20 10:13:27 +02:00
Max Kellermann
17562dc90b output/pipewire: remove misplaced noexcept 2021-10-20 09:41:27 +02:00
Max Kellermann
7b24316734 output/pipewire: fix coding style 2021-10-20 09:41:10 +02:00
Max Kellermann
5fab107fd3 lib/nfs/FileReader: use the thread-safe InjectEvent
.. instead of DeferEvent, which is not thread-safe.  This caused
various playback problems, which was initially caused by the
DeferEvent/InjectEvent split in commit 774b4313f2

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1298
2021-10-20 09:38:09 +02:00
Max Kellermann
f31920e092 event/Loop: add thread assert() to AddDefer()
Currently fails in class NfsFileReader due to
https://github.com/MusicPlayerDaemon/MPD/issues/1298
2021-10-20 09:26:27 +02:00
Max Kellermann
eb111a10e7 output/pipewire: remove redundant prefix and newline from log message 2021-10-19 14:38:37 +02:00
Max Kellermann
80b09360c6 NEWS: mention the previous commit 2021-10-19 14:38:37 +02:00
Nicolai Syvertsen
5ccf78855d Implement SendTag for PipeWire output plugin 2021-10-19 14:31:40 +02:00
Max Kellermann
fd5a3b5880 client/Response: reimplement Error() without FmtError()
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
2021-10-19 13:40:11 +02:00
Max Kellermann
6120c1360c neighbor/Glue: remove unreachable "throw" statement
Should have been removed by commit a8087dc12c
2021-10-19 13:40:11 +02:00
Max Kellermann
a8087dc12c neighbor/Glue: mention failed plugin name in error message 2021-10-19 13:29:00 +02:00
Max Kellermann
070c03dbf7 event/Thread, ...: fix printf->libfmt remains 2021-10-19 13:19:07 +02:00
Max Kellermann
0a9bec3754 increment version number to 0.23.2 2021-10-19 10:29:49 +02:00
Max Kellermann
fff25ac753 release v0.23.1 2021-10-19 10:27:28 +02:00
Max Kellermann
4f1e79b6b8 filter/ReplayGain: emit "mixer" event when replay gain changes volume
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1294
2021-10-19 10:03:21 +02:00
Max Kellermann
aa9933c0b5 output/pipewire: add noexcept 2021-10-19 08:58:50 +02:00
Max Kellermann
0697d1f859 output/pipewire: include cleanup 2021-10-19 08:57:33 +02:00
Max Kellermann
df033fa4aa NEWS: mention the previous commit 2021-10-19 08:56:32 +02:00
Nicolai Syvertsen
b941a7df83 Implement volume updates for pipewire output 2021-10-19 00:01:45 +02:00
Max Kellermann
31151cec3c command/playlist: "load" supports relative positions
This commit also increases the PROTOCOL_VERSION so clients can detect
the availability of the feature.
2021-10-18 22:08:22 +02:00
Max Kellermann
07e8c338df command/queue: move position parameter functions to separate library 2021-10-18 22:07:04 +02:00
Max Kellermann
b22d7218aa command/player, ...: use decimal notation
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
2021-10-18 16:54:53 +02:00
Max Kellermann
d5be8c74b0 output/pipewire: attempt to change the graph sample rate
Requires PipeWire 0.3.32.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1283
2021-10-18 16:46:23 +02:00
Max Kellermann
c112cb60da output/snapcast: fix typo which caused "Failed to get chunk"
This bug caused a 9 second offset in all time stamps.  Due to that,
the Snapcast server thought the chunks are too old and discarded them.

Fixes https://github.com/MusicPlayerDaemon/MPD/discussions/1287
2021-10-18 16:40:11 +02:00
Max Kellermann
677fa4f9bc doc/plugins.rst: mention that the snapcast output requires a format 2021-10-17 20:01:21 +02:00
Max Kellermann
907af2ad02 Permission: refactor getPermissionFromPassword() to return std::optional
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
2021-10-17 19:58:50 +02:00
Thomas Zander
6a2e7bbc02 protocol/ArgParser.cxx: Add missing #include <stdio.h>
Fixes a build problem on platforms where stdio.h is not included
transitively. snprintf() is defined in stdio.h.
2021-10-16 17:38:07 +02:00
Max Kellermann
771c46032f meson.build: add missing libfmt dependencies
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.
2021-10-15 14:26:59 +02:00
Max Kellermann
85611aa456 storage/smbclient: add StoragePlugin.prefixes
Should have been part of commit
ef24cfa523

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1279
2021-10-15 10:24:30 +02:00
Max Kellermann
466b5cb08d neighbor/smbclient: FmtError() instead of FormatErrno()
Fixes part 2 of https://github.com/MusicPlayerDaemon/MPD/issues/1279
2021-10-15 09:40:36 +02:00
Max Kellermann
3f2f3251cb neighbor/smbclient: use [[gnu::pure]]
Fixes part 1 of https://github.com/MusicPlayerDaemon/MPD/issues/1279
2021-10-15 09:39:34 +02:00
Max Kellermann
8ae85f3991 doc/protocol.rst: move POSITION from "search" to "findadd"
Whoops, I misplaced this one.
2021-10-14 15:36:25 +02:00
Max Kellermann
781fe4ff28 increment version number to 0.23.1 2021-10-14 15:36:16 +02:00
Max Kellermann
163c59128e release v0.23 2021-10-14 15:25:21 +02:00
Max Kellermann
608896571c command/queue: add position parameter to "load"
Another one from https://github.com/MusicPlayerDaemon/MPD/issues/888
2021-10-14 15:11:11 +02:00
Max Kellermann
2e5ca1cbd2 command/database: add "position" parameter to "findadd" and "searchadd"
Closes https://github.com/MusicPlayerDaemon/MPD/issues/888
2021-10-14 15:03:02 +02:00
Max Kellermann
680fb51c37 Permission: add "player" to default permission set
Forgot that in commit 9a766f4cd9
2021-10-14 14:58:38 +02:00
Max Kellermann
77d74b404e Permission: add option "host_permissions"
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1115
2021-10-14 14:44:18 +02:00
Max Kellermann
a636d2127a Permission: add "pure" attributes 2021-10-14 14:26:51 +02:00
Max Kellermann
9a766f4cd9 Permission: split permission "player" from "control"
Some users want certain clients to fully control playback, but do not
want them to be able to trigger database update.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1124
2021-10-14 14:19:51 +02:00
Max Kellermann
8ad17d25ef player/CrossFade: do not cross-fade songs shorter than 20 seconds
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
2021-10-14 13:47:24 +02:00
Max Kellermann
46d00dd85f player/CrossFade: move code to CanCrossFadeSong() 2021-10-14 13:42:27 +02:00
Max Kellermann
ec52b13449 player/CrossFade: add method IsEnabled() 2021-10-14 13:41:50 +02:00
Max Kellermann
cf6ca1b0ba player/CrossFade: use C++11 initializers 2021-10-14 13:38:42 +02:00
Max Kellermann
37bd6de658 db/simple: add option to hide CUE target songs
This reduces duplicates in the music database by hiding the original
song file when it is referenced by a CUE sheet.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1275
2021-10-14 13:28:37 +02:00
Max Kellermann
f7622ca332 db/update/Walk: move PurgeDanglingFromPlaylists() to Playlist.cxx 2021-10-14 13:12:10 +02:00
Max Kellermann
b82b56970b db/simple/Song: reorder fields for better packing 2021-10-14 12:55:02 +02:00
Max Kellermann
e4eb5b79c9 output/shout: move shout_new() call to Enable()
Don't allocate any memory until the output is really enabled.
2021-10-14 12:28:36 +02:00
Max Kellermann
1cfea20b22 output/shout: remove the defunct "timeout" option
The implementation was removed 12 years ago in commit f6455d5f79 and
nobody missed it.
2021-10-14 12:04:13 +02:00
Max Kellermann
efa3ffa8d8 Revert "db/update/playlist: remove non-existent targets while scanning"
This reverts commit 9200fa6d06.  It was
wrong because it works only if the target song has already been
scanned.
2021-10-14 11:50:41 +02:00
Max Kellermann
1b8c94d6b9 db/update/Playlist: move code to another UpdatePlaylistFile() method 2021-10-14 11:36:45 +02:00
Max Kellermann
cd5c1f3f45 db/update/playlist: remove empty playlist directories 2021-10-13 19:23:24 +02:00
Max Kellermann
9200fa6d06 db/update/playlist: remove non-existent targets while scanning 2021-10-13 19:23:24 +02:00
Max Kellermann
1bbe9896f6 Main: make inotify errors non-fatal 2021-10-13 18:55:05 +02:00
Max Kellermann
2d8847f428 db/update/InotifyUpdate: convert to class, no global variables 2021-10-13 18:47:56 +02:00
Max Kellermann
72f6e018e7 Log: remove the obsolete printf-style functions 2021-10-13 17:41:19 +02:00
Max Kellermann
2fbbd540bb more [[gnu::...]] attributes 2021-10-13 17:38:01 +02:00
Max Kellermann
18f64b5fb7 system/FatalError: remove obsolete library 2021-10-13 16:53:01 +02:00
Max Kellermann
d2a8b1e8a5 db/update/InotifySource: make errors non-fatal 2021-10-13 16:53:01 +02:00
Max Kellermann
184e8eca7c win32/Win32Main: throw on error 2021-10-13 16:37:56 +02:00
Max Kellermann
0a8886704a Main: move top-level exception handler to main()
Allows win32_main() to throw exceptions.
2021-10-13 16:37:34 +02:00
Max Kellermann
0712314d23 archive/{zzip,iso9660}: ignore file names which are invalid UTF-8
These malformed strings must not be transferred over the wire, because
the MPD protocol is defined to be UTF-8.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1274
2021-10-13 15:51:08 +02:00
Max Kellermann
f8cbba1850 util/Alloc: remove unused library 2021-10-13 14:48:16 +02:00
Max Kellermann
635ec3ce37 util/VarSize: use plain malloc() 2021-10-13 14:46:40 +02:00
Max Kellermann
8e71130e8a tag/FixString: use class AllocatedArray 2021-10-13 14:40:33 +02:00
Max Kellermann
ed7baf3ae1 tag/Id3Scan: use StringView::Strip() instead of duplicating the string 2021-10-13 14:32:43 +02:00
Max Kellermann
1e159af2ce tag/Id3Scan: merge duplicate code into InvokeOnTag() 2021-10-13 14:30:57 +02:00
Max Kellermann
dffed6e393 tag/Id3Scan: add class Id3String 2021-10-13 14:24:17 +02:00
Max Kellermann
bf656af555 playlist/SoundCloud: use AllocatedString for concatenation 2021-10-13 12:47:57 +02:00
Max Kellermann
d2b8852d19 playlist/SoundCloud: move code to TranslateSoundCloudUri() 2021-10-13 12:23:15 +02:00
Max Kellermann
7d4de71899 sticker/SongSticker: use AllocatedString for concatenation 2021-10-13 12:19:45 +02:00
Max Kellermann
e1c16d78e4 decoder/wavpack: use AllocatedString for concatenation 2021-10-13 12:15:57 +02:00
Max Kellermann
a49b49cba7 decoder/wavpack: fix WVC file support
The wrong variable was used.  This has been broken by commit
4eeea640f4 seven years ago - and nobody as noticed, d'oh!
2021-10-13 12:11:39 +02:00
Max Kellermann
f510564d9d more [[gnu::...]] attributes 2021-10-13 12:07:05 +02:00
Max Kellermann
1c4b484a56 avahi/Poll: use FineTimerEvent in AvahiTimeout
libavahi-client uses this one to schedule events immediately.
However, CoarseTimerEvent may be called too late, and cause timeouts.
2021-10-13 11:13:54 +02:00
Max Kellermann
b394d8d059 net/Resolver: include cleanup 2021-10-13 11:06:10 +02:00
Max Kellermann
a15c1c71d5 util/WritableBuffer: add WritableBuffer<void>::{FromVoid,ToVoid}() 2021-10-13 11:05:33 +02:00
Max Kellermann
8d679e7e00 util/IntrusiveList: add IntrusiveList::swap() 2021-10-13 11:04:42 +02:00
Max Kellermann
2b30ac2351 util/IntrusiveList: add another missing ToNode() call 2021-10-13 11:04:21 +02:00
Max Kellermann
1c97793b49 util/IntrusiveList: do not use the deprecated class std::iterator
Deprecated in C++17.  Since C++17, one is supposed to declare those 5
types manually.
2021-10-13 11:03:49 +02:00
Max Kellermann
4dae8b41da event/PipeEvent: new class wrapping SocketEvent 2021-10-13 10:45:55 +02:00
Max Kellermann
be8ed2f59e tag/Settings: use [[gnu::const]] 2021-10-13 10:37:26 +02:00
Max Kellermann
08491fcd86 tag/Format: use [[gnu::pure]] 2021-10-13 10:37:26 +02:00
Max Kellermann
abed633fcb tag/FixString: use [[gnu::pure]] 2021-10-13 10:37:26 +02:00
Max Kellermann
db2a9cb6d5 tag/Builder: use [[gnu::pure]] 2021-10-13 10:37:26 +02:00
Max Kellermann
7caeb3b0d8 tag/ParseName: use [[gnu::pure]] 2021-10-13 10:32:22 +02:00
Max Kellermann
08500be239 tag/VorbisComment: use [[gnu::pure]] 2021-10-13 10:31:51 +02:00
Max Kellermann
3ef7d8fecb tag/Tag: use [[gnu::pure]] 2021-10-13 10:31:51 +02:00
Max Kellermann
ffde7223b9 tag/Table: use [[gnu::pure]] 2021-10-13 10:31:51 +02:00
Max Kellermann
4e84fa4a00 RemoteTagCache: use [[gnu::pure]] 2021-10-13 10:31:51 +02:00
Max Kellermann
78e49928b6 command/QueueCommands: disallow moving the current song relative to itself
This was a no-op previously, but this operation makes no sense.
2021-10-07 22:55:41 +02:00
Max Kellermann
c0bcfe244c command/QueueCommands: reimplement relative "move"/"moveid" offsets
The existing implementation has been utterly broken forever; I cannot
explain what it actually does, but it doesn't do what the
documentation says.
2021-10-07 22:49:38 +02:00
Max Kellermann
e63ecd81ec command/QueueCommands: eliminate id lookup from handle_addid()
Use MoveRange() instead of MoveId().
2021-10-07 22:44:06 +02:00
Max Kellermann
c47a858d15 command/QueueCommands: move code to RequireCurrentPosition() 2021-10-07 22:21:00 +02:00
Max Kellermann
076c9a0dd9 command/QueueCommands: offset relative "addid" positions by one
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.
2021-10-07 22:12:10 +02:00
Max Kellermann
3993176b76 command/QueueCommands: support relative offsets in "addid"
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
2021-10-07 21:55:56 +02:00
Max Kellermann
16cad48641 command/QueueCommands: validate the "addid" position before adding the song
Validate early, so we avoid the rollback if an error occurs.
2021-10-07 21:27:07 +02:00
Max Kellermann
7a6d0c2efc command/Queue: move LookupRemoteTag() to the end
Skip the LookupRemoteTag() call if the MoveId() call fails.
2021-10-07 21:13:45 +02:00
Max Kellermann
f6035f2dda util/UriRelative: use std::string_view
Eliminates lots of implicit std::string temporaries.
2021-10-07 14:49:53 +02:00
Max Kellermann
c34a1e29de util/UriRelative: fix variable mixup 2021-10-07 14:44:41 +02:00
Max Kellermann
41a69027c2 test/util/TestUriRelative: add failing test for "./" prefix 2021-10-07 14:44:30 +02:00
Max Kellermann
711c614528 python/build/libs.py: update WildMidi to 0.4.4 2021-10-07 13:34:04 +02:00
Max Kellermann
6acb240f69 python/build/libs.py: update CURL to 7.79.1 2021-10-07 13:31:00 +02:00
Max Kellermann
45f3dd8b7a Revert "python/build/libs.py: remove flac, switch to Meson wrap"
This reverts commit 6ed4aff4d3.  The
Meson wrap is broken on non-x86, because it unconditionally includes
<cpuid.h> which is an x86 only header.
2021-10-07 13:28:17 +02:00
James D. Smith
acc1bd6297 playlist/PlaylistSong: Remove dots from playlist file paths. 2021-10-07 13:15:40 +02:00
James D. Smith
49ed9dae34 util/UriUtil: New uri_squash_dot_segments. 2021-10-07 13:14:54 +02:00
Max Kellermann
cf554d306d LocateUri: implement UriPluginKind::STORAGE properly
This way, URI schemes supported by arbitrary storage plugins are
allowed.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1270
2021-10-06 20:36:39 +02:00
Max Kellermann
ef24cfa523 storage/Plugin: add "prefixes" 2021-10-06 20:14:01 +02:00
Max Kellermann
5d35983298 decoder/openmpt: catch libopenmpt exceptions in scan_stream()
Fixes crash bug.
2021-10-06 20:14:01 +02:00
Max Kellermann
2dacb36789 LocateUri: throw std::invalid_argument instead of std::runtime_error
This should translate to ACK_ERROR_ARG instead of ACK_ERROR_UNKNOWN.
2021-10-06 19:26:33 +02:00
Max Kellermann
57a1403f08 output/pipewire: implement Delay(), fix busy loop while paused
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1265
2021-09-24 11:33:35 +02:00
Max Kellermann
bad3283182 output/pipewire: add flag "active", replaces some uses of "paused"
This way, we know whether we're explicitly "paused" or "not yet
activated because the ring buffer hasn't been filled yet".
2021-09-24 11:33:30 +02:00
Max Kellermann
6ed4aff4d3 python/build/libs.py: remove flac, switch to Meson wrap 2021-09-21 16:44:51 +02:00
Max Kellermann
e525465592 python/build/verify.py: support SHA256 2021-09-21 16:22:21 +02:00
Max Kellermann
10782f4c84 {android,win32}/build.py: use makedirs(exist_ok) 2021-09-21 16:04:31 +02:00
Max Kellermann
2a02576d6d python/build/meson.py: move c_args, ... to [built-in options]
As per Meson 0.56.0:
 https://mesonbuild.com/Machine-files.html#properties
2021-09-21 14:57:55 +02:00
Max Kellermann
9ea1578a97 lib/expat/meson.build: propagate the libexpat dependency
Fixes the build with libexpat from Meson wrap.
2021-09-21 14:38:00 +02:00
Max Kellermann
520028dcfc python/build/libs.py: remove libexpat, switch to Meson wrap 2021-09-21 14:08:23 +02:00
Max Kellermann
e98cef06c7 python/build/meson.py: remove --libdir=lib MultiArch workaround
Not necessary anymore since Meson 0.50.0:
 https://mesonbuild.com/Release-notes-for-0-50-0.html#libdir-defaults-to-lib-when-cross-compiling
2021-09-21 13:58:45 +02:00
Max Kellermann
aef0535c55 python/build/libs.py: remove libvorbis, switch to Meson wrap 2021-09-21 13:49:50 +02:00
Max Kellermann
6b1d0cb01d meson.build: disable compiler warnings for subprojects
Requires Meson 0.56.0:
 https://mesonbuild.com/Release-notes-for-0-56-0.html#per-subproject-warning_level-option
2021-09-21 13:48:16 +02:00
Max Kellermann
f23ecf00da meson.build: set per-subproject "default_library"
Requires Meson 0.54.0:
 https://mesonbuild.com/Release-notes-for-0-54-0.html#per-subproject-default_library-and-werror-options
2021-09-21 13:41:45 +02:00
Max Kellermann
a1c1e26875 meson.build: require Meson 0.56.0
I want to use per-subproject warning_level (0.56.0), default_library
(0.54.0).
2021-09-21 13:39:44 +02:00
Max Kellermann
410b8711f2 lib/curl/meson.build: add -DCURL_STATICLIB on Windows
Necessary since commit 6acf81d5ae
2021-09-21 13:24:35 +02:00
Max Kellermann
6acf81d5ae python/build/libs.py: build CURL with cmake 2021-09-21 12:30:39 +02:00
Max Kellermann
4eb56d844e python/build/libs.py: update Boost to 1.77.0 2021-09-21 12:22:17 +02:00
Max Kellermann
5faf6d061f python/build/libs.py: build expat with cmake 2021-09-20 23:23:20 +02:00
Max Kellermann
d5a9f6d79d python/build/libs.py: build libogg, libvorbis with cmake 2021-09-20 23:23:20 +02:00
Max Kellermann
2699889342 python/build/cmake.py: use CMAKE_TOOLCHAIN_FILE
Let cmake know that we're cross-crompiling.
2021-09-20 23:14:13 +02:00
Max Kellermann
e4f933361e python/build/libs.py: update OpenSSL to 3.0.0 2021-09-20 22:54:02 +02:00
Max Kellermann
6f278977e9 build/python/project: add build(), calls _build()
Prepare to add some code around the _build() call.
2021-09-20 22:54:02 +02:00
Max Kellermann
4f2f705dca build/python/make: rename build() to build_make()
Eliminate conflict with other Project classes.
2021-09-20 22:54:02 +02:00
Max Kellermann
f31e38145d python/build/cmake.py: some ccache support 2021-09-20 22:54:02 +02:00
Max Kellermann
0231622169 build/python/cmake: add "windows_configure_args" 2021-09-20 22:46:54 +02:00
Max Kellermann
937423dbcf event/Loop: check the quit flag after RunDeferred()
Allow DeferredEvents to call EventLoop::Break().
2021-09-10 12:14:18 +02:00
Rosen Penev
40483d8478 fix wrong emplace usage
emplace already calls std::pair. No need for it again.

No need to emplace when calling std::make_shared.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2021-09-07 21:14:37 -07:00
Rosen Penev
6ec5089cc9 remove std::make_pair
make_pair is an old C++98 function that can be replaced by modern
shorter constructs.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2021-09-07 21:13:22 -07:00
iconoclasthero
15f419e1cb Update user.rst
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
2021-09-06 12:41:41 -04:00
Max Kellermann
bdd8c34c67 Merge branch 'move' of git://github.com/neheb/MPD 2021-08-29 06:47:05 +02:00
Max Kellermann
c9a9248c9f java/Class: use Java::LocalObject
This eliminates all but one DeleteLocalRef() call.
2021-08-28 08:09:54 +02:00
Max Kellermann
31f7fede30 java/GlobalRef: remove method Set(), always require initialization 2021-08-28 08:08:30 +02:00
Max Kellermann
917fe549b0 java/Object: use type aliases 2021-08-28 08:05:57 +02:00
Max Kellermann
8e430e55af Java/GlobalRef: add LocalRef cast constructor 2021-08-28 08:04:20 +02:00
Max Kellermann
9e61bda592 java/String: add class StringUTFChars() 2021-08-27 12:30:43 +02:00
Max Kellermann
56997290d7 io/BufferedOutputStream: add method Discard() 2021-08-27 12:06:36 +02:00
Max Kellermann
d2f84f3df8 io/BufferedOutputStream: allow specifying the buffer size 2021-08-27 12:06:20 +02:00
Max Kellermann
9da28e5c73 io/BufferedOutputStream: more API documentation 2021-08-27 12:06:02 +02:00
Max Kellermann
d1f9b06f84 io/BufferedOutputStream: add WriteT() 2021-08-27 12:05:26 +02:00
Max Kellermann
f9f3306db9 io/BufferedOutputStream: use std::size_t 2021-08-27 12:05:06 +02:00
Max Kellermann
19d19cd737 fs/io/BufferedOutputStream: avoid including windows.h
Include the most specific header documented by MSDN instead.
2021-08-27 12:04:44 +02:00
Max Kellermann
b1175acb59 util/StringView: hard-code C++17 2021-08-27 12:01:31 +02:00
Max Kellermann
672278e5fd util/StringView: use [[gnu::]] attributes 2021-08-27 11:59:37 +02:00
Max Kellermann
da155f8822 util/StringCompare: use [[gnu::]] attributes 2021-08-27 11:58:25 +02:00
Max Kellermann
4026ef63b6 util/StringAPI: use [[gnu::]] attributes 2021-08-27 11:57:56 +02:00
Max Kellermann
b282682ba5 use using instead of typedef 2021-08-27 11:57:33 +02:00
Max Kellermann
ad00926e1b util/AllocatedArray: add method release() 2021-08-27 11:24:50 +02:00
Rosen Penev
0b774df375 prevent use after move
These should be equivalent anyway.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2021-08-26 13:38:36 -07:00
Rosen Penev
53ffcf455c make several member functions const
Signed-off-by: Rosen Penev <rosenp@gmail.com>
2021-08-26 13:15:52 -07:00
Max Kellermann
9ca64d5fb3 filter/Chain: eliminate, just use a chain of TwoFilters instead
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.
2021-08-26 17:45:23 +02:00
Max Kellermann
bd79354f32 filter/TwoFilters: add ChainFilters() 2021-08-26 17:42:25 +02:00
Max Kellermann
49dcac5c21 filter/TwoFilters: add class PreparedTwoFilters 2021-08-26 17:36:19 +02:00
Max Kellermann
38a4b0d8d5 filter/TwoFilters: fix include guard 2021-08-26 14:36:52 +02:00
Max Kellermann
a224225e48 pcm/AudioFormat: use std::size_t 2021-08-26 13:42:15 +02:00
Max Kellermann
7d7fe756b3 pcm/AudioFormat: use [[gnu::pure]] 2021-08-26 13:42:15 +02:00
Max Kellermann
1cb7fe12ff pcm/AudioFormat: add noexcept 2021-08-26 13:37:36 +02:00
Max Kellermann
8a29805767 Merge tag 'v0.22.11'
release v0.22.11
2021-08-24 22:19:38 +02:00
Max Kellermann
94c196108d release v0.22.11 2021-08-24 22:15:22 +02:00
Max Kellermann
263d1ba002 Main: playlist_directory defaults to "/sdcard/Android/data/org.musicpd/files/playlists"
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1233
2021-08-24 22:12:27 +02:00
Max Kellermann
2dba06dc34 android/Context: add GetExternalFilesDir() 2021-08-24 22:03:53 +02:00
Max Kellermann
811860c3b4 android/Context: use [[gnu::pure]] 2021-08-24 21:54:22 +02:00
Max Kellermann
8439119e24 filter/ffmpeg: support double-precision samples
Insert an "aformat" filter which converts double-precision to
single-precision.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1235
2021-08-24 13:45:57 +02:00
Max Kellermann
b5b40d8235 filter/ffmpeg: automatically retry with "aformat"
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
2021-08-24 13:31:13 +02:00
Max Kellermann
b904f8af03 lib/ffmpeg/Filter: add FilterContext::MakeAformat() 2021-08-24 13:30:17 +02:00
Max Kellermann
ebfbb74f9e lib/ffmpeg/DetectFilterFormat: return AudioFormat::Undefined() on EAGAIN 2021-08-24 13:30:03 +02:00
Max Kellermann
7b4225aa1f lib/ffmpeg/Filter: add ParseSingleInOut()
Merge some duplicate code.
2021-08-24 13:29:08 +02:00
Max Kellermann
71a5311b06 lib/ffmpeg/Filter: eliminate class FilterContext
Since AVFilterContext are freed automatically, this wrapper class
serves no purpose.  Let's remove it.
2021-08-24 13:04:34 +02:00
Max Kellermann
a62a35e1db lib/ffmpeg/Filter: remove FilterContext destructor
Fixes potential double-free bugs which currently did not occur because
the destructors happened to be called in the right order.
2021-08-24 12:56:05 +02:00
Max Kellermann
ca2439f595 filter/ffmpeg: pass "channel_layout" instead of "channels" to buffersrc
Fixes part 1 of https://github.com/MusicPlayerDaemon/MPD/issues/1235
2021-08-23 21:38:13 +02:00
Max Kellermann
f9a0db716a android: build with NDK r23 2021-08-23 20:58:19 +02:00
Max Kellermann
34aa67ea87 Merge remote-tracking branches 'neheb/6', 'neheb/5', 'neheb/3', 'neheb/2' and 'neheb/1' 2021-08-23 20:36:26 +02:00
Dave Hocker
18be8c3318 Fix compile error on macOS 11.15.2 (introduced by commit 30e3ef4) 2021-08-21 11:16:22 -05:00
Rosen Penev
1d7a8f992f clang-tidy: use auto
The type is duplicated otherwise

Found with modernize-use-auto

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2021-08-21 00:53:23 -07:00
Rosen Penev
da1783cdff clang-tidy: remove pointless const
Found with readability-const-return-type

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2021-08-21 00:51:21 -07:00
Rosen Penev
20d74bb07e clang-tidy: replace loop with std::all_of
Found with readability-use-anyofallof

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2021-08-21 00:49:36 -07:00
Rosen Penev
0f7a0b04ca replace loop with find_if
loop is wrong anyway. It's missing a break;

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2021-08-21 00:48:30 -07:00
Rosen Penev
40c6a214e3 unique_ptr/new to make_unique
The latter is easier to read and is the "correct" thing to do.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2021-08-20 23:54:14 -07:00
Samir Benmendil
cfe024ea13 command/file: return directory_uri if real_uri is unset
Prevent a segfault when accessing album art.

Fix  
2021-08-17 10:55:43 +02:00
Max Kellermann
993d85125e increment version number to 0.22.11 2021-08-17 10:55:10 +02:00
Max Kellermann
bedcf1cce5 Merge branch 'exp2' of git://github.com/neheb/MPD 2021-08-17 10:53:36 +02:00
Rosen Penev
30e3ef4c8e constexpr/std::array conversions
Signed-off-by: Rosen Penev <rosenp@gmail.com>
2021-08-16 21:05:56 -07:00
Rosen Penev
4c5fea96e4 constexpr global variable conversion
Found with cppcoreguidelines-avoid-non-const-global-variables

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2021-08-16 20:58:21 -07:00
Rosen Penev
46600931e4 clang-tidy: use default
Found with modernize-use-default

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2021-08-16 20:48:28 -07:00
Max Kellermann
a2387210bf time/FileTime: move code to SystemClock.hxx 2021-08-10 19:53:53 +02:00
Max Kellermann
d7e7adb496 time/FileTime: add ChronoToFileTime() 2021-08-10 16:16:15 +02:00
Max Kellermann
45354a421c time/FileTime: preserve the FILETIME resolution
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.
2021-08-10 15:16:59 +02:00
Max Kellermann
9fc3c60910 time/FileTime: add FileTimeToChronoDuration() 2021-08-10 15:13:22 +02:00
Max Kellermann
1976003e91 time/FileTime: allow negative times 2021-08-10 15:13:16 +02:00
Max Kellermann
488afc47d4 time/FileTime: use uint_least64_t 2021-08-10 15:12:49 +02:00
Max Kellermann
017814adc7 test/time/TestFileTime: new unit test 2021-08-10 15:12:34 +02:00
Max Kellermann
7f94af8b2c test/time/TestISO8601: disable on Windows for now 2021-08-10 15:07:19 +02:00
Max Kellermann
09d74f05c3 python/meson: set exe_wrapper=wine for Windows builds
Allows running the unit tests on Linux.
2021-08-10 15:04:54 +02:00
Max Kellermann
1af8694ef6 python/meson: set needs_exe_wrapper=true only for Android targets 2021-08-10 15:00:58 +02:00
Max Kellermann
b8eb9b466a python/meson: split the f.write() call and use f-strings 2021-08-10 15:00:58 +02:00
Max Kellermann
bd9e449b69 python/project: re-add support for version suffix
Got lost in commit 0f56ddb805
2021-08-10 15:00:58 +02:00
Max Kellermann
f3d67115d7 output/wasapi: check ENABLE_DSD before setting dsd_mode 2021-08-10 15:00:58 +02:00
Max Kellermann
ee6603ed38 test/meson.build: add missing dependencies on libfmt 2021-08-10 14:31:49 +02:00
Max Kellermann
0dacde32f2 output/pipewire: append output name to PW node name 2021-08-10 11:30:25 +02:00
Max Kellermann
528e05f025 output/pipewire: add config option "remote" 2021-08-10 11:28:29 +02:00
Max Kellermann
269583f5dd output/pipewire: allow specifying a target by its name 2021-08-10 11:17:16 +02:00
Max Kellermann
7c9f4f7e4f output/pipewire: create inactive stream, fill ring_buffer first
This avoids underruns at the start of playback.
2021-08-10 10:50:42 +02:00
Max Kellermann
00fd692eba output/pipewire: wait for buffer to fill before resuming 2021-08-10 10:48:25 +02:00
Max Kellermann
668c3782b2 output/pipewire: smaller ring buffer, 500ms should be enough 2021-08-10 10:43:56 +02:00
Max Kellermann
1e0af2dadf output/pipewire: add type alias for boost::lockfree::spsc_queue 2021-08-10 10:43:54 +02:00
Max Kellermann
4ea2ea2a52 output/pipewire: update nbytes after calling PcmSilence()
This was missing in commit 8a243e6e28
2021-08-10 10:43:28 +02:00
Max Kellermann
8a243e6e28 output/pipewire: call pw_stream_flush() only if really draining
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
2021-08-10 06:30:58 +02:00
Max Kellermann
d33aa01000 output/pipewire: reset the "paused" flag
This was missing in commit 4d1ce7023b
2021-08-09 19:31:22 +02:00
Max Kellermann
bd893e6336 Merge tag 'v0.22.10'
release v0.22.10
2021-08-06 18:21:59 +02:00
Max Kellermann
64c39af556 release v0.22.10 2021-08-06 18:16:59 +02:00
Max Kellermann
04eb911a51 mixer/alsa: use cached values to work around rounding errors
This replaces 967af60327 with a more
effective workaround.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/822
2021-08-06 18:16:37 +02:00
Max Kellermann
351b39e0c5 mixer/alsa: skip the snd_mixer_handle_events() call in alsa_mixer_elem_callback()
snd_mixer_handle_events() has already been called by
DispatchSockets().  This way, we can also skip the exception handler.
2021-08-06 18:03:36 +02:00
Max Kellermann
3b6d4e6673 mixer/alsa: move alsa_mixer_elem_callback() into the AlsaMixer class 2021-08-06 18:01:19 +02:00
Max Kellermann
e8f328d8ad mixer/alsa: move code to GetPercentVolume() 2021-08-06 17:56:30 +02:00
Max Kellermann
5f5b5f63af mixer/alsa: move code to NormalizedToPercent() 2021-08-06 17:55:59 +02:00
Max Kellermann
ad6e303047 mixer/alsa: move code to GetNormalizedVolume() 2021-08-06 17:53:45 +02:00
Max Kellermann
b0e9538855 build/openssl: pass --cross-compile-prefix to ./Configure 2021-08-06 17:30:47 +02:00
Max Kellermann
694debd4cc build/openssl: pass RANLIB=... to "make install"
The "install_dev" target runs ranlib during installation, and this
can break the Android build.
2021-08-06 17:28:28 +02:00
Max Kellermann
0f56ddb805 python/build/libs.py: update OpenSSL to 3.0.0-beta2 2021-08-06 17:22:41 +02:00
Max Kellermann
dde77ec6bd python/build/libs.py: update CURL to 7.78.0 2021-08-06 17:20:52 +02:00
Max Kellermann
5d73eda115 doc/plugins.rst: move filter graph URL to ffmpeg.org 2021-08-06 17:20:52 +02:00
Max Kellermann
1985786ed2 db/simple: prune CUE entries from database for non-existent songs
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1019
2021-08-05 20:26:21 +02:00
Max Kellermann
8e0d39ae94 db/update/Playlist: prepend "../" only for relative URIs
Prepending "../" to absolute URIs would break them.
2021-08-05 20:19:33 +02:00
Max Kellermann
1761fb14af fs/Traits: add PathTraitsUTF8::IsAbsoluteOrHasScheme() 2021-08-05 20:09:06 +02:00
Max Kellermann
ef2fc4e6f6 db/simple/Directory: remove obsolete API doc 2021-08-05 19:05:03 +02:00
Max Kellermann
b979245d6c decoder/Bridge: call UpdateStreamTag() only if there is no pending seek
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
2021-08-05 18:02:45 +02:00
Max Kellermann
a74b07728e tag/Tag: add Merge() which takes Tag pointers 2021-08-05 17:36:14 +02:00
Max Kellermann
7d69cbbda7 tag/Tag: Merge() returns Tag, MergePtr() returns std::unique_ptr<Tag> 2021-08-05 17:32:23 +02:00
Constantin Fuerst
955502f881 output/oss: enable DoP
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.
2021-08-05 16:21:43 +02:00
Max Kellermann
dee5d1b87b output/oss: replace the AudioFormat field with 3 raw OSS integers
This simplifies Reopen().
2021-08-05 16:03:53 +02:00
Max Kellermann
d42342e0ba output/oss: check returned value in oss_try_ioctl() 2021-08-05 15:53:30 +02:00
Max Kellermann
8da3f8c6a7 output/oss: oss_try_ioctl() throws on EINVAL
Eliminate some duplicate code.
2021-08-05 15:47:11 +02:00
Max Kellermann
c8c553c75c pcm/Export: add method IsDopEnabled() 2021-08-05 15:35:11 +02:00
Max Kellermann
c97aabe43a Merge branch 'v0.22.x' 2021-08-05 15:17:07 +02:00
Max Kellermann
17b0ac75ca output/oss: always enable PcmExport for alsa_channel_order
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.
2021-08-05 15:11:54 +02:00
Max Kellermann
bde64a13e2 tag/Builder: do not acquire tag_pool_lock if TagItem list is empty 2021-08-05 14:32:58 +02:00
Max Kellermann
96875921b7 tag/Builder: use std::swap() in move operator
This way, we save the overhead for acquiring the tag_pool_lock.
2021-08-05 14:28:37 +02:00
Cebtenzzre
551c941b5a tag/Builder: don't ignore the result of tag_pool_dup_item
Also, use RemoveAll() instead of directly clearing TagBuilder::items in
most cases, as its elements represent references that must be released.

Closes 
2021-08-05 14:25:55 +02:00
Cebtenzzre
624c77ab43 tag/Builder: another missing RemoveAll() call 2021-08-05 14:25:05 +02:00
Cebtenzzre
ba13b4b5d6 tag/Builder: use RemoveAll() to give up references 2021-08-05 14:23:48 +02:00
Cebtenzzre
4b2d9e544c tag/Pool: add [[nodiscard]] 2021-08-05 14:20:59 +02:00
Max Kellermann
97c43954e8 input/tidal: remove defunct unmaintained plugin
This plugin has been defunct for several years.  Tidal has not ever
replied to any of my emails, so they're apparently not interested in
MPD support.
2021-08-05 13:52:05 +02:00
Max Kellermann
b77acd35f7 output/winmm: fix struct/class mismatch 2021-08-05 11:40:47 +02:00
Max Kellermann
4873159872 meson.build: add "fallback" option to fmt dependency (for older Meson versions) 2021-08-05 11:28:23 +02:00
Max Kellermann
968624035c mixer/pipewire: new plugin 2021-08-05 10:57:37 +02:00
Max Kellermann
b838bf3109 output/pipewire: un-inline StateChanged() 2021-08-05 10:48:17 +02:00
Max Kellermann
4d1ce7023b output/pipewire: implement Pause() 2021-08-04 17:26:54 +02:00
Max Kellermann
52577ac87a output/pipewire: implement Cancel() properly 2021-08-04 17:24:49 +02:00
Max Kellermann
9fa3984a2f input/icy: adjust offset at end of stream in Read()
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
2021-08-02 16:40:04 +02:00
Max Kellermann
239698cb5a output/pipewire: set channel positions 2021-07-30 15:55:37 +02:00
Max Kellermann
e55de6e9f0 output/pipewire: implement Drain() 2021-07-30 15:28:01 +02:00
Max Kellermann
cfaf2ed03c output/pipewire: move code to CheckThrowError() 2021-07-30 15:24:20 +02:00
Max Kellermann
6015960871 output/pipewire: reset the "interrupted" flag in Cancel()
This fixes seeking.
2021-07-30 15:20:32 +02:00
Max Kellermann
26328cc915 output/pipewire: detect connection errors 2021-07-30 14:31:06 +02:00
Max Kellermann
cd512f0b40 output/pipewire: replace usleep() with with pw_thread_loop_wait() 2021-07-30 14:31:04 +02:00
Max Kellermann
be14dd59a8 output/pipewire: remove obsolete TODO comment 2021-07-30 13:50:55 +02:00
Max Kellermann
97e5787ff7 output/pipewire: call libpipewire only while holding the lock
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1210
2021-07-30 13:49:22 +02:00
Max Kellermann
6975d3ca4b output/pipewire: switch from pw_main_loop to pw_thread_loop
We need this for pw_thread_loop_lock().
2021-07-30 13:42:59 +02:00
Max Kellermann
cdca27e6bb decoder/Bridge: fix libfmt string 2021-07-30 13:32:27 +02:00
Max Kellermann
5355335f19 db/simple/ExportedSong: check src.OwnsTag(), not this->OwnsTag()
this->OwnsTag() accesses fields that are not yet initialized.
2021-07-30 13:10:09 +02:00
Sam Bazley
5b775ca5b4 decoder/ffmpeg: check if long_name is not null 2021-07-28 16:05:15 +01:00
Jacob Vosmaer
ea95da3b1a archive/meson.build: add missing libfmt dependency 2021-07-26 23:26:07 +02:00
Sam Bazley
57687779be Android: add option to pause MPD when headphones disconnect 2021-07-26 19:02:47 +01:00
Max Kellermann
64fa76c568 command/file: support "albumart" for virtual tracks in CUE sheets
Instead of checking for "cover.jpg" in the virtual directory
representing the CUE sheet, check its enclosing directory.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1206
2021-07-16 09:04:35 +02:00
Max Kellermann
19a44076cf command/file: pass directory uri to read_stream_art() 2021-07-16 08:31:58 +02:00
Max Kellermann
809a18913a fs/Traits: add overload GetParent(string_view) 2021-07-16 08:30:34 +02:00
Max Kellermann
5eab2d96f4 output/winmm: fix struct/class mismatch 2021-07-16 08:30:34 +02:00
Max Kellermann
716784f632 increment version number to 0.22.10 2021-07-16 07:23:00 +02:00
Khem Raj
d39b11ba5d include <utility> for std::forward
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>
2021-06-29 19:34:28 -07:00
Max Kellermann
b29a43b4d7 decoder/mad, ...: more libfmt logging 2021-06-25 20:52:08 +02:00
Max Kellermann
f60a42e0b6 Log, client/Response: adapt to libfmt 8.0.0 API changes 2021-06-25 20:29:25 +02:00
Max Kellermann
85b0029ba2 meson.build: add missing dependencies on libfmt 2021-06-25 20:28:54 +02:00
Max Kellermann
0e0f46a1e0 Log: remove unused Format functions 2021-06-24 21:40:12 +02:00
Max Kellermann
6f539cfcd6 Partition, ...: use libfmt for logging 2021-06-24 21:40:11 +02:00
Max Kellermann
0185d58a2b Log: add libfmt support 2021-06-24 21:14:42 +02:00
Naglis Jonaitis
eb630ca655 doc/user.rst: rectify admin permission
Updating the database no longer requires the `admin` permission, only
`control` is needed (changed in 2abad0f479).

See also: 
2021-06-24 16:44:38 +02:00
Max Kellermann
d7df5e1c90 LogBackend: pass std::string_view to Log() 2021-06-24 13:43:13 +02:00
Max Kellermann
e4e4576a39 Merge tag 'v0.22.9'
release v0.22.9
2021-06-23 21:02:06 +02:00
Max Kellermann
18628bf89e release v0.22.9 2021-06-23 20:56:13 +02:00
Yetangitu
2052b461af Fix android build error when confronted with package versions ending in +revision_information
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
2021-06-23 20:53:46 +02:00
Max Kellermann
5019bdcd52 TagAny: invoke ScanGenericTags() on remote files
This fixes reading ID3 tags on remote files with the commands
"readcomments" and "readpicture".

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1180
2021-06-23 20:49:30 +02:00
Naglis Jonaitis
8be0bcbdb9 doc/plugins.rst: mention default libsamplerate type 2021-06-23 15:51:31 +02:00
Naglis Jonaitis
af72a22ed8 doc/user.rst: document restore_paused 2021-06-23 15:50:41 +02:00
Naglis Jonaitis
6ed9668fea doc, README.md: update IRC server name/URL 2021-06-23 15:48:42 +02:00
Max Kellermann
175d2c6d29 Main: use AtScopeExit() to call ZeroconfDeinit()
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
2021-06-22 20:31:45 +02:00
Naglis Jonaitis
f789451007 doc/plugins.rst: fix PipeWire link 2021-06-19 21:29:37 +03:00
Max Kellermann
36680607d0 meson.build: use some warning options for plain C as well 2021-06-01 11:14:28 +02:00
Max Kellermann
fc54877c6b meson.build: merge duplicate warning flags to test_common_flags 2021-06-01 11:04:27 +02:00
Rosen Penev
6af7be4a45 add constexpr
Found with cppcoreguidelines-interfaces-global-init

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2021-05-31 13:45:39 -07:00
Max Kellermann
ab487b9a99 Android: use startForegroundService() in Android 8+
Fixes the error:

 IllegalStateException: Not allowed to start service Intent { cmp=org.musicpd/.Main (has extras) }: app is in background
2021-05-31 20:45:31 +02:00
Max Kellermann
ac59ec34f9 decoder/ffmpeg: fix build failure with FFmpeg 3.4
av_demuxer_iterate() was added in libavformat 58.9.100.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1178
2021-05-31 18:10:06 +02:00
Max Kellermann
82da57b7ce decoder/ffmpeg: suppress -Wunused with libavformat<58.6.100 2021-05-31 16:49:48 +02:00
Max Kellermann
aa6dac9bd2 db/proxy: suppress -Wunused with libmpdclient<2.12 2021-05-31 16:49:08 +02:00
Rosen Penev
220d2bf026 clang-tidy: add explicit deleted constructors
Found with cppcoreguidelines-special-member-functions

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2021-05-30 22:47:20 -07:00
Rosen Penev
9ef1cf15a9 clang-tidy: default virtual destructors
Found with cppcoreguidelines-special-member-functions

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2021-05-30 22:46:46 -07:00
Max Kellermann
679b3bc00f output/print, command/player: print bool as integer
Fixes protocol breakage after commit 0440c41cba

libfmt is too clever for the MPD protocol!

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1175
2021-05-28 18:02:00 +02:00
Max Kellermann
1f9e32c35e NEWS: fix typo 2021-05-28 15:46:38 +02:00
Max Kellermann
36410daaa4 queue/PlaylistEdit: fix inverted check
Regression by commit 471c37be59

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1135
2021-05-28 13:56:01 +02:00
Max Kellermann
38bfef7d0b Merge branch 'add-openmpt-decoder' of git://github.com/GrimReaperFloof/MPD 2021-05-28 13:53:43 +02:00
GrimReaperFloof
724754f16c Fix std::to_string warning for booleans in openmpt decoder 2021-05-27 20:47:45 +02:00
Max Kellermann
4d32454697 android/LogListener: pass formatted message to OnLog() 2021-05-27 16:21:36 +02:00
Max Kellermann
4db882f666 android/LogListener: cache the jmethodID 2021-05-27 16:14:43 +02:00
Max Kellermann
a83bf97b98 android/LogListener: un-inline the constructor 2021-05-27 16:13:22 +02:00
Max Kellermann
262e1957b7 lib/icu/Converter: use libfmt 2021-05-27 16:09:56 +02:00
Max Kellermann
792411384d protocol/ArgParser: add function MakeArgError()
Replaces FormatProtocolError().
2021-05-27 16:01:44 +02:00
Max Kellermann
78b0ff83e8 client/Response: include cleanup 2021-05-27 15:59:06 +02:00
Max Kellermann
23613355f3 client/Response: remove unused method FormatV() 2021-05-27 15:16:35 +02:00
Max Kellermann
0d97eba7a5 client/Response: refactor FormatError() to use libfmt 2021-05-27 15:15:47 +02:00
Max Kellermann
18efda719e client/Response: remove unused method Format() 2021-05-27 15:14:54 +02:00
Max Kellermann
42239a30eb client/Response: use Fmt() in FormatError() 2021-05-27 15:05:42 +02:00
Max Kellermann
a26bf261a9 input/last: call Close() in Open()
Prevents a possible bug which occurs when the caller-provided open()
function throws; then the "uri" field is never set.
2021-05-27 14:04:28 +02:00
Max Kellermann
c692286c67 input/last: clear "uri" field in Close()
Prevent false negative after the stream was closed automatically after
20 seconds.
2021-05-27 14:03:33 +02:00
GrimReaperFloof
43a9dc7082 Add note about emulate_amiga_type requiring libopenmpt 0.5 2021-05-26 23:43:38 +02:00
GrimReaperFloof
6f64fa070d Add repeat count setting to openmpt decoder 2021-05-26 23:43:38 +02:00
GrimReaperFloof
dc5b9d989b Backwards compatibility with older libopenmpt versions than 0.5 2021-05-26 23:43:38 +02:00
GrimReaperFloof
9e407f5989 Change WritableBuffer<uint8_t> to AllocatedArray<std::byte> 2021-05-26 23:43:38 +02:00
GrimReaperFloof
fec6aac0f1 Code deduplication: move mod_loadfile() into ModCommon.cxx 2021-05-26 23:43:38 +02:00
GrimReaperFloof
541c31c879 Add openmpt decoder plugin 2021-05-26 23:43:38 +02:00
Max Kellermann
4ee0a06e18 Merge branch 'v0.22.x' 2021-05-26 13:15:29 +02:00
Max Kellermann
3775766605 NEWS: mention new FFmpeg/ID3v2 tags 2021-05-26 13:07:03 +02:00
Max Kellermann
38e24208f6 decoder/ffmpeg: support the tags "album-sort", "artist-sort" 2021-05-26 13:04:47 +02:00
Max Kellermann
fbaedf2262 decoder/ffmpeg: support the "sort_album" tag
From libavformat/mov.c.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1173
2021-05-26 13:03:47 +02:00
Max Kellermann
8f3341cefb decoder/ffmpeg: add comment 2021-05-26 13:03:41 +02:00
Max Kellermann
4ec4bab3a9 decoder/ffmpeg: remove "year" tag
This mapping was added 11 years ago in commit 766b9fd453, but FFmpeg
doesn't appear to support it.
2021-05-26 13:03:27 +02:00
Max Kellermann
6d567bcd35 decoder/ffmpeg: fix ArtistSort and AlbumArtistSort mapping
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.
2021-05-26 13:03:26 +02:00
Max Kellermann
4f75eb9bfe output/pipewire: remove unreachable "return" statement 2021-05-26 11:57:57 +02:00
Max Kellermann
d2bd12822f Merge branch 'v0.22.x' 2021-05-26 11:57:41 +02:00
Max Kellermann
363d9f0180 db/update/Walk: load all .mpdignore files of all parent directories
When updating everything, this did work, but if updating only a
subdirectory, the ".mpdignore" in the parents were not used.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1172
2021-05-25 22:42:44 +02:00
Max Kellermann
db0682a469 db/update/Walk: move code to LoadExcludeList() 2021-05-25 22:38:01 +02:00
Max Kellermann
7a6823dcdf zeroconf/AvahiPoll: the struct timeval is an absolute time point
Fixes broken libavahi-client timeouts.
2021-05-25 22:25:45 +02:00
Max Kellermann
bce144a232 zeroconf/AvahiPoll: move code to Schedule() 2021-05-25 22:23:55 +02:00
Max Kellermann
0cef84cac6 zeroconf/AvahiPoll: rename "timer" to "event" 2021-05-25 22:23:55 +02:00
Max Kellermann
56c0733b42 meson.build: disable -Wsuggest-override with GCC 8 2021-05-25 22:23:55 +02:00
Max Kellermann
0b0acb3981 meson.build: add more C++ warning flags 2021-05-25 22:03:49 +02:00
Max Kellermann
1375dcc4ec meson.build: sort warning options 2021-05-25 21:49:03 +02:00
Max Kellermann
6aeb0e335b meson.build: add comment for -Wno-non-virtual-dtor 2021-05-25 21:48:19 +02:00
Max Kellermann
c1e2537851 meson.build: add comment for clang-only warning options 2021-05-25 21:45:39 +02:00
Max Kellermann
8c690fb737 decoder/mad: move variable declaration into "case" 2021-05-25 21:34:09 +02:00
Max Kellermann
dad1c21b59 zeroconf/avahi: move variable declaration into "case" 2021-05-25 21:34:09 +02:00
Max Kellermann
dd10b2bd61 meson.build: remove warning options implied by -Wall -Wextra 2021-05-25 21:24:44 +02:00
Max Kellermann
48c7c540df meson.build: use add_project_arguments() instead of add_global_arguments()
Don't propagate MPD-specific compiler flags to subprojects.
2021-05-25 21:08:06 +02:00
Max Kellermann
281270cd2a meson.build: remove unused variables common_cflags, common_cxxflags 2021-05-25 21:07:05 +02:00
Max Kellermann
02502514f6 meson.build: require clang 7 (remove bug workaround) 2021-05-25 21:06:55 +02:00
Max Kellermann
1bc02123f9 meson.build: remove "-pedantic", implied by Meson
Meson adds "-Wpedantic" in warning_level 3 (which is MPD's default).
2021-05-25 21:01:15 +02:00
Max Kellermann
3488a47c41 subprojects/sqlite3.wrap: add SQLite wrap 2021-05-25 20:51:03 +02:00
Max Kellermann
fd82d67678 sticker/Database: pass NarrowPath to sqlite3_open()
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1171
2021-05-25 18:45:45 +02:00
Max Kellermann
e66c12105b lib/sqlite/meson.build: add missing external dependency on libsqlite 2021-05-25 18:41:43 +02:00
Max Kellermann
8a9d678bac Merge branch 'v0.22.x' 2021-05-25 18:21:42 +02:00
Namkhai B
dbe12a6b90 util/RuntimeError: Disable format-security for gcc
Fixes building under GCC 11
2021-05-25 18:19:19 +02:00
Max Kellermann
0440c41cba client/Response: add method Fmt() based on libfmt 2021-05-25 16:01:56 +02:00
Max Kellermann
a9c704b76e meson.build: libfmt integration 2021-05-25 15:48:49 +02:00
Philippe Antoine
d3a680cc87 meson: set only sanitizers for fuzzer when unspecified
That is when meson option b_sanitize is not used
2021-05-24 09:03:16 +02:00
Max Kellermann
62fc4d5cf4 increment version number to 0.22.9 2021-05-24 09:03:07 +02:00
Max Kellermann
0cca1b138c Merge tag 'v0.22.8'
release v0.22.8
2021-05-22 17:35:30 +02:00
Max Kellermann
14465be847 release v0.22.8 2021-05-22 17:33:36 +02:00
Max Kellermann
0e49de867d input/last: add nullptr check to Open(), fixes assertion failure
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1168
2021-05-22 17:33:25 +02:00
Max Kellermann
f2e4529707 increment version number to 0.22.8 2021-05-22 17:32:00 +02:00
Max Kellermann
d3576a1b71 input/last: add nullptr check to Open(), fixes assertion failure
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1165
2021-05-21 19:30:36 +02:00
Max Kellermann
96707c0426 Merge tag 'v0.22.7'
release v0.22.7
2021-05-19 18:43:19 +02:00
Max Kellermann
3547fc7e61 release v0.22.7 2021-05-19 18:13:26 +02:00
Max Kellermann
466a05bc52 CommandLine: update copyright year in --version output 2021-05-19 18:09:38 +02:00
Max Kellermann
6de4064cca client/Response, command/file: use %lu instead of %zu on Windows
Fixes -Wformat warnings.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1150
2021-05-19 18:06:40 +02:00
Max Kellermann
bcf0fdd3a8 meson.build: define NOUSER on Windows for lighter windows.h
A few exceptions are needed for sources which include COM header
(directly or indirectly).

This fixes lots of shadow warnings, see
https://github.com/MusicPlayerDaemon/MPD/issues/1150
2021-05-19 18:02:49 +02:00
Max Kellermann
a8f05a7efc win32/HResult: un-inline HRESULTToString() to reduce header dependencies 2021-05-19 17:48:42 +02:00
Max Kellermann
c64a3b5dbb fs/Glob: un-inline the Windows version to reduce header dependencies 2021-05-19 17:41:23 +02:00
Max Kellermann
16c38c438f fs/Glob: use defaulted move constructor 2021-05-19 17:40:23 +02:00
Max Kellermann
48cc4a6ced fs/Glob: remove redundant #ifdefs 2021-05-19 17:40:03 +02:00
Max Kellermann
a169a05e41 win32, ...: avoid including windows.h
Include the most specific header documented by MSDN instead.
2021-05-19 17:25:32 +02:00
Max Kellermann
a6cb3139db meson.build: disable Windows header features not needed by MPD 2021-05-19 17:16:16 +02:00
Max Kellermann
239a83324e meson.build: document Windows definitions 2021-05-19 17:15:25 +02:00
Max Kellermann
8efa5c7641 output/wasapi: use "%lu" in log calls
"%lu" is portable - it works with both POSIX and Microsoft flavors.

Fixes a part of https://github.com/MusicPlayerDaemon/MPD/issues/1150
2021-05-19 17:10:49 +02:00
Max Kellermann
28e7be248f util/RuntimeError: disable -Wformat-security as a kludge 2021-05-19 14:57:20 +02:00
Max Kellermann
e016cc8940 lib/upnp/meson.build: auto-disable UPnP without CURL/expat 2021-05-19 14:37:13 +02:00
GrimReaperFloof
34f636ffc3 Change WritableBuffer<uint8_t> to AllocatedArray<std::byte> 2021-05-19 09:54:06 +02:00
GrimReaperFloof
a134f692bf Code deduplication: move mod_loadfile() into ModCommon.cxx 2021-05-19 09:53:39 +02:00
Max Kellermann
d747576793 Merge branch 'npu' of git://github.com/neheb/MPD 2021-05-19 09:48:12 +02:00
Max Kellermann
d9578f6427 Merge branch 'flac-ogg' of git://github.com/jprjr/VGMPD 2021-05-19 09:33:42 +02:00
Max Kellermann
b2cec7a0a3 Merge branch 'v0.22.x' 2021-05-19 08:09:05 +02:00
Max Kellermann
85db2d6704 db/proxy: split search into chunks to avoid exceeding the output buffer
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1130
2021-05-19 08:04:50 +02:00
Max Kellermann
22ebb2bdd5 db/proxy: send "window" as separate parameter to SendConstraints() 2021-05-19 07:51:48 +02:00
Max Kellermann
e108568082 db/proxy: require libmpdclient 2.11 or later
Remove lots of #ifdefs.
2021-05-19 07:46:42 +02:00
Max Kellermann
360381e65d doc/plugins.rst: mention the minimum MPD version 2021-05-19 07:46:42 +02:00
Max Kellermann
3ead778664 doc/plugins.rst: add libmpdclient website link 2021-05-19 07:45:47 +02:00
Max Kellermann
4fc08e39b4 db/proxy: require MPD 0.20 or later
Allows using ranges, always.  This is required to fix
https://github.com/MusicPlayerDaemon/MPD/issues/1130 without adding
more runtime conditionals.
2021-05-19 07:41:04 +02:00
Max Kellermann
c3f9b38c97 command/PlaylistCommands: pass real_uri to LookupRemoteTag()
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
2021-05-18 21:35:09 +02:00
Max Kellermann
dbb18a401b command/file: cache the last "albumart" file
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1156
2021-05-18 17:04:09 +02:00
Max Kellermann
e1e41708af input/LastInputStream: new class 2021-05-18 17:04:09 +02:00
Max Kellermann
a2bdac571a Merge branch 'v0.22.x' 2021-05-17 19:33:15 +02:00
Max Kellermann
638dfc3981 {input,storage}/curl: set CURLOPT_HTTPAUTH=CURLAUTH_BASIC
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
2021-05-17 19:26:05 +02:00
Max Kellermann
7c09e44ad4 python/build/libs.py: update OpenSSL to 3.0.0-alpha16 2021-05-17 18:42:05 +02:00
Max Kellermann
365b798f33 python/build/libs.py: update FFmpeg to 4.4 2021-05-17 18:42:05 +02:00
Max Kellermann
6f51d910ee python/build/libs.py: update CURL to 7.76.1 2021-05-17 18:42:05 +02:00
Max Kellermann
1215818572 doc/meson.build: remove "upload" target
Since we migrated to readthedocs.io, we don't need this target
anymore.  And Meson 0.58.0 apparently has a change breaking this
target.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1161
2021-05-17 18:33:00 +02:00
John Regan
87fa6bca54 flac encoder: enable Ogg FLAC and Ogg chaining
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.
2021-05-15 11:31:01 -04:00
Max Kellermann
c3226a3195 doc/conf.py: Copyright 2021 2021-05-11 17:57:14 +02:00
Max Kellermann
51671af5a4 doc/conf.py: move "~git" suffix to release 2021-05-11 17:52:24 +02:00
Max Kellermann
2908f6565b doc/conf.py: update version number to 0.23~git 2021-05-11 17:49:26 +02:00
skidoo23
514ed33a02 python/build: update Boost URL and version 2021-05-11 13:11:16 +02:00
GrimReaperFloof
a0334d1d94 Add resampling mode setting to modplug decoder 2021-05-07 19:48:52 +02:00
Max Kellermann
bfed47b82d .travis.yml: switch the OSX build to xcode11.6
The clang/libc++ version in xcode10.3 does not support C++17 properly
and cannot build MPD.
2021-04-28 13:40:36 +02:00
Max Kellermann
8c51440057 test/test_mixramp: workaround for -Wdouble-promotion 2021-04-28 13:00:42 +02:00
Max Kellermann
018858ec97 .travis.yml: install standard Homebrew GTest formula 2021-04-27 16:23:23 +02:00
Max Kellermann
3c1988b68f .travis.yml: switch from Ubuntu Bionic to Ubuntu Focal (20.04) 2021-04-27 16:23:23 +02:00
Max Kellermann
5452428d69 .travis.yml: switch to ppa:ricotz/toolchain for ninja 1.8 on Ubuntu Trusty
The old "ppa:mstipicevic/ninja-build-1-7-2" just provides ninja 1.7
which is too old and breaks the build.
2021-04-27 16:23:23 +02:00
Max Kellermann
d6bf6e161a .travis.yml: remove obsolete comment 2021-04-27 15:48:19 +02:00
Max Kellermann
a71b76bb3c test/test_pcm_format: another workaround for -Wdouble-promotion 2021-04-26 23:25:36 +02:00
Max Kellermann
c1429500b2 test/test_pcm_format: work around -Wdouble-promotion 2021-04-26 22:21:12 +02:00
Max Kellermann
0f02bbc2fe output/jack: enable on Windows
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.
2021-04-26 21:47:20 +02:00
Max Kellermann
b885f358a5 output/control: add missing nullptr checks
Fixes crash when pausing the default partition after an output was
moved to another partition.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1147
2021-04-26 21:34:58 +02:00
Max Kellermann
423f2df5e0 pcm/Volume: drop support for GCC older than 8 2021-04-20 20:01:43 +02:00
Max Kellermann
0122dc8452 util/BindMethod: drop support for GCC older than 7 2021-04-20 20:01:08 +02:00
Max Kellermann
650a30d794 Revert "tag/Pool: use strncmp() without strlen() to compare strings"
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.
2021-04-15 16:15:44 +02:00
Max Kellermann
1dc71f383a python/build/boost.py: touch boost/version.hpp to avoid reinstalling all the time 2021-04-07 13:50:05 +02:00
Max Kellermann
95ad1b0cc6 use [[gnu::pure]] instead of gcc_pure
This is semi-standard and doesn't require the util/Compiler.h header.
2021-04-06 14:09:21 +02:00
Max Kellermann
52f46b94e9 util/AllocatedString: add concatenating constructor 2021-04-06 14:06:16 +02:00
Max Kellermann
e07e0bc9c1 util/AllocatedArray: include cleanup 2021-04-06 14:05:29 +02:00
Max Kellermann
4a1c231734 net/SocketError: use constexpr 2021-04-06 13:59:58 +02:00
Max Kellermann
fd0e958e95 net/SocketError: use auto 2021-04-06 13:58:46 +02:00
Max Kellermann
3d814115c8 net/SocketError: change "const" to "pure" 2021-04-06 13:58:32 +02:00
Max Kellermann
ca726a0110 util/StringBuffer: make capacity() static
This allows using it in constant expressions.
2021-04-06 13:46:07 +02:00
Max Kellermann
e01710cbd1 util/DereferenceIterator: simplify operator->()
This makes it compatible with containers storing std::unique_ptr.
2021-04-06 13:45:32 +02:00
Max Kellermann
c87a4a7d08 util/DereferenceIterator: fix static_cast in operator->() 2021-04-06 13:45:10 +02:00
Max Kellermann
b59170b702 Java/Exception: simplify RethrowException() 2021-04-06 13:35:59 +02:00
Max Kellermann
a237db556a java/File: add non-static GetAbsolutePath() overload 2021-04-06 13:35:59 +02:00
Max Kellermann
285ba54fe5 java/String: remove unnecessary env parameter 2021-04-06 13:35:59 +02:00
Max Kellermann
ee86434a89 java/String: add const 2021-04-06 13:35:59 +02:00
Max Kellermann
95d5efbfe6 java/Ref: add nullptr comparison 2021-04-06 13:35:59 +02:00
Max Kellermann
c33f206ce8 java/Ref: add nullptr constructor 2021-04-06 13:29:35 +02:00
Max Kellermann
2d95ac2e94 Java/String: inherit the super class constructor 2021-04-06 13:29:24 +02:00
Max Kellermann
f58c14a74a Java: no namespace indent 2021-04-06 13:29:13 +02:00
Max Kellermann
a52ce7bb7b java/Ref: add move operator 2021-04-06 13:27:11 +02:00
Max Kellermann
16d187b7ed java/Ref: remove const, add default initialiser 2021-04-06 13:26:54 +02:00
Max Kellermann
296ec4d07c java/Ref: add nullptr check to destructor
May allow the compiler to optimize calls away.
2021-04-06 13:26:29 +02:00
Max Kellermann
6e58fd1583 lib/curl/Multi: reword API documentation 2021-03-29 20:19:21 +02:00
Max Kellermann
c5fec4ac2a lib/curl/Multi: move operator bool() down 2021-03-29 20:19:21 +02:00
Max Kellermann
fe2ca1ddef lib/curl/Multi: rename parameters 2021-03-29 20:19:19 +02:00
Jean-Francois Dockes
e960626804 Add npupnp support
libnpupnp is a C++ modification of libupnp.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2021-03-26 14:14:58 -07:00
Simon Persson
7dd2dce6ad Support new tags in proxy plugin
Add support for the following tags when using the proxy database plugin:
WORK
CONDUCTOR
LABEL
GROUPING
MUSICBRAINZ_WORKID
COMPOSERSORT
ENSEMBLE
MOVEMENT
MOVEMENTNUMBER
LOCATION
2021-03-24 20:59:54 +01:00
Max Kellermann
a7ba10423d Merge branch 'v0.22.x' 2021-03-13 08:41:10 +01:00
John Regan
6dfebf7df9 gme: add support for rsn files
Upcoming release of game-music-emu will support it, details here: https://bitbucket.org/mpyne/game-music-emu/pull-requests/23/rsn-support
2021-03-13 08:40:25 +01:00
Shen-Ta Hsieh
4bcdcca7f5 output/wasapi: use calculated new buffer instead old one 2021-03-13 08:39:56 +01:00
bitkeeper
c08a8581ee Added cross-origin header to http headers of the http output.
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: *
2021-03-10 21:27:19 +01:00
Simon Persson
8f1e7385b7 Add tags relevant to classical music.
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".
2021-03-10 21:24:25 +01:00
Max Kellermann
25354b9d8c Merge branch 'v0.22.x' 2021-03-10 21:06:12 +01:00
Max Kellermann
25b0194036 output/wasapi: implement Drain() 2021-03-10 21:05:48 +01:00
Max Kellermann
77fe727e69 output/wasapi: move the "is_started" flag to class WasapiOutputThread 2021-03-10 20:43:28 +01:00
Max Kellermann
73f9824ddf output/wasapi: eliminate friend declaration 2021-03-10 20:38:41 +01:00
Max Kellermann
1fe0c673bc output/wasapi: implement Cancel() properly
Calling consume_all() is illegal in the producer thread.
2021-03-10 20:38:27 +01:00
Max Kellermann
8a045207a7 output/wasapi: add field paused
Fixes bogus Delay() results at the start of playback, because Delay()
thinks the output is paused.
2021-03-10 20:09:37 +01:00
Max Kellermann
fe7c5a4208 output/wasapi: initialize is_started in Open() 2021-03-10 20:07:22 +01:00
Max Kellermann
8024f7e84d output/wasapi: move the thread->Play() call right before the consumed_size check
Fixes a bogus assertion failure (which can now be removed).
2021-03-10 20:07:19 +01:00
Max Kellermann
14f0134097 output/wasapi: make device_config const 2021-03-10 20:05:14 +01:00
Max Kellermann
1da27be84d output/wasapi: move runtime fields below configuration fields 2021-03-10 20:00:08 +01:00
Max Kellermann
08135f2cb7 output/wasapi: make configuration fields const 2021-03-10 19:58:33 +01:00
Max Kellermann
5907656bbb output/wasapi: stop the IAudioClient while paused
Instead of generating silence, do nothing, don't waste CPU time.
2021-03-10 17:48:49 +01:00
Max Kellermann
2ac2bd26f8 output/wasapi: combine two if statements to one switch 2021-03-10 17:45:54 +01:00
Max Kellermann
a2be91aea5 output/wasapi: add method WasapiOutputThread::InterruptWaiter() 2021-03-10 17:42:26 +01:00
Max Kellermann
579428172e output/wasapi: remove the broken Delay() calculation code
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().
2021-03-10 17:39:07 +01:00
Max Kellermann
3e484637f9 output/wasapi: rename OpenDevice() to ChooseDevice()
OpenDevice was a confusing name because it does not actually open a
device.
2021-03-10 17:34:10 +01:00
Max Kellermann
3e93c392d7 output/wasapi: make enumerator a local variable 2021-03-10 17:23:41 +01:00
Max Kellermann
0a97e68aa9 output/wasapi: start after the buffer has been filled
Postpone the Start() call until there is something to be played.
2021-03-08 23:03:25 +01:00
Max Kellermann
69783a44c8 output/wasapi: move Start()/Stop() calls to WasapiOutputThread::Work() 2021-03-08 22:58:20 +01:00
Max Kellermann
d72263d28d win32/HResult: support AUDCLNT_E_NOT_{INITIALIZED,STOPPED} 2021-03-08 22:57:44 +01:00
Max Kellermann
24a205a1aa win32/HResult: try to use FormatMessage() 2021-03-08 22:54:46 +01:00
Max Kellermann
3a948515ce output/wasapi: check for exceptions after Wait()
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).
2021-03-08 22:46:40 +01:00
Max Kellermann
9ade93983c output/wasapi: rename method WaitDataPoped() to Wait() 2021-03-08 22:44:49 +01:00
Max Kellermann
6931ce9558 output/wasapi: make the Thread a field, not a base class 2021-03-08 22:30:19 +01:00
Max Kellermann
d6fb07a3e4 output/wasapi: start the WasapiOutputThread in its constructor 2021-03-08 22:29:33 +01:00
Max Kellermann
01d3c2705e output/wasapi: Finish() calls Join() 2021-03-08 22:28:36 +01:00
Max Kellermann
29346dc9c5 output/wasapi: remove the thread management code from DoDisable()
This is duplicate; this has already been done in Close().
2021-03-08 22:27:46 +01:00
Max Kellermann
d19b3df3b0 test/run_output: call AudioOutput::Drain() 2021-03-08 22:20:55 +01:00
Max Kellermann
798e68ef62 output/wasapi: don't clear the exception in CheckException()
This is pointless; the method cannot be called again anyway.
2021-03-08 22:18:48 +01:00
Max Kellermann
79397db5b4 output/wasapi: remove the "thrown" field
It is pointless to let WasapiOutputThread wait for the
CheckException() call.
2021-03-08 22:17:45 +01:00
Max Kellermann
9256190a9b output/wasapi: move catch block to the Work() function level
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).
2021-03-08 22:15:36 +01:00
Max Kellermann
3a0dbb0a67 output/wasapi: make WasapiOutputThread::is_exclusive const 2021-03-08 22:09:23 +01:00
Max Kellermann
3d6c9d1b88 output/wasapi: catch all exception 2021-03-08 22:06:29 +01:00
Max Kellermann
5823e79fe7 output/wasapi: remove broken Drain() implementation
The current Drain() implementation does what Cancel() should do; it
does not wait for completion, but instead discards the buffer.
2021-03-08 21:41:34 +01:00
Max Kellermann
5f656dffda output/wasapi: implement Cancel() 2021-03-08 19:58:15 +01:00
Max Kellermann
34d4d9157a output/wasapi: add inline 2021-03-08 19:57:40 +01:00
Max Kellermann
22c329cdb4 output/wasapi: convert pointer to reference 2021-03-08 19:56:56 +01:00
Max Kellermann
980ef82216 output/wasapi: move SetEventHandle() call to thread constructor 2021-03-08 17:52:44 +01:00
Max Kellermann
84a06a72df output/wasapi: fix coding style 2021-03-08 17:52:43 +01:00
Max Kellermann
4833d0891d output/wasapi: eliminate kErrorId 2021-03-08 17:47:07 +01:00
Max Kellermann
cd53ca22c6 output/wasapi: remove unused function SafeTry() 2021-03-08 17:43:36 +01:00
Max Kellermann
4d9af9a81b test/run_{input,output,convert}: switch file descriptors to binary mode
Fixes those programs on Windows.
2021-03-08 17:27:23 +01:00
Max Kellermann
d61341c0e3 io/FileDescriptor: add method SetBinaryMode() 2021-03-08 17:25:36 +01:00
Max Kellermann
eff50b263a test/run_output: use class StaticFifoBuffer 2021-03-08 17:01:48 +01:00
Max Kellermann
2bebc79363 test/run_convert: use std::byte 2021-03-08 16:58:43 +01:00
Max Kellermann
e777fb4edb test/run_convert: pass FileDescriptor to RunConvert() 2021-03-08 16:51:57 +01:00
Max Kellermann
3fb25d4062 test/run_convert: move code to RunConvert() 2021-03-08 16:46:21 +01:00
Max Kellermann
e227596c20 test/run_output: pass FileDescriptor to run_output() 2021-03-08 16:44:15 +01:00
Max Kellermann
ec76583c33 win32/Com: add COINIT_DISABLE_OLE1DDE
MSDN documentation suggests always passing this flag to reduce
overhead for an "obsolete technology".
2021-03-08 14:03:33 +01:00
Max Kellermann
927f1e03a3 win32/Com: make COINIT_APARTMENTTHREADED the default constructor 2021-03-08 14:02:49 +01:00
Max Kellermann
f2c679cfec win32/Com: remove the unused COINIT_MULTITHREADED constructor 2021-03-08 14:02:49 +01:00
Max Kellermann
6a75c48dba win32/HResult: add MakeHResultError()
None of the current FormatHResultError() callers need the format string.
2021-03-08 13:46:36 +01:00
Max Kellermann
48bdd09f64 win32/ComWorker: fold class COMWorkerThread into class COMWorker 2021-03-07 18:22:59 +01:00
Max Kellermann
cf108c389f win32/ComWorker: remove parameter passing from Async()
Parameters should better be captured.  This removes some complexity
from Async().
2021-03-07 18:20:59 +01:00
Max Kellermann
90d97053a8 win32/ComWorker: make COMWorker a real class, no static members 2021-03-06 20:46:29 +01:00
Max Kellermann
ee720064a7 Merge branch 'v0.22.x' 2021-03-05 19:41:17 +01:00
Shen-Ta Hsieh
e1fe9ebcd6 output/wasapi: Add dop support for WASAPI
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1102
2021-03-05 19:40:32 +01:00
Max Kellermann
e1b62fb90d Merge branch 'v0.22.x' 2021-03-05 19:33:46 +01:00
Max Kellermann
93016ac6ab output/wasapi: check AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWED
Stop early, don't try more formats if it is clear that we have no
chance.
2021-03-05 19:33:38 +01:00
Max Kellermann
fc20a1f10a output/wasapi: EnumerateDevices() logs, no std::vector 2021-03-05 19:27:52 +01:00
Max Kellermann
a4257e51d5 output/wasapi: reimplement SearchDevice() without EnumerateDevices() 2021-03-05 19:25:42 +01:00
Max Kellermann
2f2b3f1cdc output/wasapi: SearchDevice() returns IMMDevice 2021-03-05 19:25:42 +01:00
Max Kellermann
2ff6a9ad2b output/wasapi: GetDevice() returns IMMDevice 2021-03-05 19:25:42 +01:00
Max Kellermann
17d4873b60 output/wasapi: use default device only if none was configured 2021-03-05 19:25:42 +01:00
Max Kellermann
8b41c4f384 output/wasapi: release the COMWorker if OpenDevice() fails
Fixes assertion failure in the Thread destructor.
2021-03-05 19:25:42 +01:00
Max Kellermann
17f7098e27 output/wasapi: SafeTry() catches all exceptions
Fixes crash due to std::stoul() throwing std::invalid_argument.
2021-03-05 19:12:22 +01:00
Max Kellermann
9ff790b7bb output/wasapi: move COM utilities to separate headers 2021-03-05 18:33:31 +01:00
Max Kellermann
ebc1fe2821 win32/ComPtr: operator*() returns reference 2021-03-05 17:39:48 +01:00
Max Kellermann
bc2988144e test/run_output: use OptionParser, add option "--verbose" 2021-03-05 17:39:48 +01:00
Max Kellermann
b1a9958c66 test/run_output: add struct CommandLine 2021-03-05 17:39:48 +01:00
Max Kellermann
e6a81bb95c output/wasapi: split the header
Reduce header dependencies.
2021-03-05 16:43:44 +01:00
Max Kellermann
9521c1ad58 output/wasapi: use forward declarations in the header 2021-03-05 16:42:38 +01:00
Max Kellermann
6d65cc48d7 output/wasapi: use [[gnu::pure]] 2021-03-05 16:42:15 +01:00
Max Kellermann
681956a963 output/wasapi: include cleanup 2021-03-05 16:42:14 +01:00
Max Kellermann
052f64d648 output/wasapi: include config.h for ENABLE_DSD 2021-03-05 16:35:21 +01:00
Max Kellermann
afe621c25c output/wasapi: move to separate directory 2021-03-05 16:28:36 +01:00
Max Kellermann
422cf5f182 Merge branch 'v0.22.x' 2021-03-05 16:05:56 +01:00
Max Kellermann
637cf8a039 win32/WinEvent: add default value to Wait() 2021-03-05 16:05:32 +01:00
Max Kellermann
2011a6e2ee win32/WinEvent: un-inline the constructor
Reduce header dependencies.
2021-03-05 16:01:23 +01:00
Max Kellermann
d54830de12 thread/WindowsFuture: include cleanup 2021-03-05 13:50:16 +01:00
Max Kellermann
a7e7312cca win32/HResult: un-inline HResultCategory::message() 2021-03-05 13:40:40 +01:00
Max Kellermann
6b83fc6b57 win32/HResult: un-inline FormatHResultError()
Reduce header dependencies.
2021-03-05 13:40:38 +01:00
Max Kellermann
74f9e07151 win32/HResult: include cleanup 2021-03-05 13:40:37 +01:00
Max Kellermann
82a61ab3be win32/meson.build: fix syntax error 2021-03-05 13:40:34 +01:00
Max Kellermann
54c1794cee win32: build static library
Fixes linker failure on test/run_output.exe
2021-03-05 13:32:58 +01:00
Max Kellermann
c962a6be76 test/run_convert: fix Windows compiler errors 2021-03-05 13:24:28 +01:00
Max Kellermann
922c4bf3f0 test/TestLookupFile: fix Windows compiler errors 2021-03-05 13:22:34 +01:00
Max Kellermann
932756efce win32/ComWorker: fix the FormatHResultError() return type
Casting to std::runtime_error loses information (and prevents RVO).
2021-03-05 13:17:40 +01:00
Max Kellermann
7838265482 win32/ComWorker: remove debug log messages 2021-03-05 13:16:09 +01:00
Max Kellermann
b14b0e5634 win32/ComWorker: reorder includes 2021-03-05 13:15:45 +01:00
Max Kellermann
4d2d0e7bb8 win32/ComWorker: include cleanup 2021-03-05 13:15:21 +01:00
Rosen Penev
44378b7dbe use structured binding declarations
Shorter.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2021-03-04 20:28:02 +01:00
Max Kellermann
ef1acb4e2f Merge branch 'v0.22.x' 2021-03-04 18:56:29 +01:00
Shen-Ta Hsieh
da642b2890 src/output: add algorithm for finding usable AudioFormat
* Use PcmExport for 24bit packed output
2021-03-04 18:53:58 +01:00
Shen-Ta Hsieh
6f77af20d0 src/output: Set fallback setting for DSD 2021-03-04 18:50:56 +01:00
Shen-Ta Hsieh
010f65a1d6 src/output: Add Interrupt interface 2021-03-04 18:50:09 +01:00
Shen-Ta Hsieh
c46f97454a src/output: Reopen device on error 2021-03-04 18:49:28 +01:00
Shen-Ta Hsieh
844dbd2ec5 src/output: Use WinEvent for as a condition_variable without lock 2021-03-04 18:46:26 +01:00
Shen-Ta Hsieh
db7caa2dac src/output: Move event and spsc_queue into thread object 2021-03-04 18:45:56 +01:00
Shen-Ta Hsieh
2974737746 src/win32: Add ComWorker to run all COM function on same thread 2021-03-04 18:43:43 +01:00
Shen-Ta Hsieh
b1d7567226 win32: Add ComWorker to run all COM function on same thread 2021-03-04 18:43:16 +01:00
Max Kellermann
5103eb3039 meson.build: compile Win32Main.cxx only on Windows 2021-03-04 18:43:00 +01:00
Shen-Ta Hsieh
0cccdcf9b2 src/win32: Add support for COINIT_APARTMENTTHREADED 2021-03-04 18:37:56 +01:00
Shen-Ta Hsieh
22b840c2f1 win32/Com: use if with init-statement 2021-03-04 18:37:35 +01:00
Shen-Ta Hsieh
ed1a995bff thread: Add Future implement for mingw32 without pthread 2021-03-04 18:26:46 +01:00
Shen-Ta Hsieh
0f39dc1edb output/wasapi: use AUDCLNT_BUFFERFLAGS_SILENT for paused output 2021-03-04 18:17:57 +01:00
Max Kellermann
dc9103befe util/AllocatedString: remove Null(), IsNull() 2021-03-04 18:05:29 +01:00
Max Kellermann
67760f5283 util/AllocatedString: support casting a nulled instance to string_view 2021-03-04 18:05:29 +01:00
Max Kellermann
99405a4c93 util/AllocatedString: add operator=() 2021-03-04 18:05:26 +01:00
Max Kellermann
b833c5d2c7 util/AllocatedString: replace Clone() with copy constructor 2021-03-04 18:04:21 +01:00
Max Kellermann
bca5d79f88 util/AllocatedString: add const_pointer constructor 2021-03-04 18:04:17 +01:00
Max Kellermann
6e1c8edf09 util/AllocatedString: add string_view constructor
Replaces the static Duplicate() method.
2021-03-04 18:04:11 +01:00
Max Kellermann
32b7b2e2fa util/AllocatedString: add default constructor 2021-03-04 18:04:06 +01:00
Max Kellermann
cfb7f8ab84 util/AllocatedString: rename to BasicAllocatedString
To make things simpler, AllocatedString is now a non-template class.
2021-03-04 18:03:56 +01:00
Max Kellermann
d4bbb8c851 Merge branch 'struc' of git://github.com/neheb/MPD 2021-03-04 17:50:53 +01:00
Érico Rolim
8d80280ab9 time/ISO8601: don't use glibc extension in strptime.
Per the manual for strptime, %F is equivalent %Y-%m-%d, so use that
directly.
2021-03-04 17:49:51 +01:00
Érico Rolim
c95e3dc065 storage/plugins/CurlStorage: don't use glibc extension in
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.
2021-03-04 17:48:23 +01:00
Max Kellermann
428f769c38 output/pipewire: new output plugin
Very rough draft.  Barely works.
2021-03-03 18:44:39 +01:00
Max Kellermann
133c8834df output/httpd: update API documentation 2021-03-02 18:24:57 +01:00
Max Kellermann
99217593bf test/util/TestIntrusiveList: add AutoUnlink test 2021-03-02 18:15:37 +01:00
Max Kellermann
1c6e4a2b18 test/util/TestIntrusiveList: new unit test 2021-03-02 18:12:15 +01:00
Max Kellermann
a6eb264770 util/IntrusiveList: add type alias "Hook"
By casting to SafeLinkIntrusiveListHook if appropriate, this fixes a
bug in the erase() method, where erase() calls
IntrusiveListHook::unlink() instead of
SafeLinkIntrusiveListHook::unlink().
2021-03-02 17:51:50 +01:00
Max Kellermann
f5f296b13a event/TimerWheel: add a "ready" list as a special case
This reduces delays of zero-duration timers from up to 1 second to
zero.  libavahi-client schedules zero-duration timers often.
2021-03-02 17:14:33 +01:00
Max Kellermann
0091c4e12b util/Exception: add FindNested() 2021-03-02 17:13:29 +01:00
Max Kellermann
80172e17ac util/Exception: remove redundant std::exception catch clause
The "std::nested_exception" catch block already covers this perfectly.
2021-03-02 17:13:21 +01:00
Max Kellermann
2d96b05403 test/util/TestException: add CheckFindRetrowNested() unit test 2021-03-02 17:12:43 +01:00
Max Kellermann
ec0c1f0d02 util/Exception: fix comment typo 2021-03-02 17:12:20 +01:00
Max Kellermann
00a520a4c3 doc/user.rst: update Windows&Android build dependencies
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1112
2021-02-26 00:59:10 +01:00
Max Kellermann
946b3c1f80 util/IntrusiveList: add method erase_and_dispose() 2021-02-25 14:12:47 +01:00
Max Kellermann
a0dc398f36 util/IntrusiveList: erase() returns an iterator 2021-02-25 14:12:39 +01:00
Max Kellermann
b54d2d984a util/IntrusiveList: use ToHook() in erase() 2021-02-25 14:12:10 +01:00
Max Kellermann
4ab73f9de9 util/IntrusiveList: add missing ToNode() cast in iterator_to() 2021-02-25 14:10:55 +01:00
Max Kellermann
5ebe23e4bb db/upnp/Discovery: use class IntrusiveList 2021-02-24 20:39:42 +01:00
Max Kellermann
aa227cded1 input/qobuz: use class IntrusiveList 2021-02-24 20:31:47 +01:00
Max Kellermann
e406bdbb80 input/tidal: use class IntrusiveList 2021-02-24 20:31:13 +01:00
Max Kellermann
1048f23680 util/IntrusiveList: add hook class SafeLinkIntrusiveListHook
Similar to boost::intrusive::safe_link.
2021-02-24 20:29:16 +01:00
Max Kellermann
8fe8f09027 util/IntrusiveList: add noexcept 2021-02-24 20:17:28 +01:00
Max Kellermann
78670c0941 util/IntrusiveList: add constexpr 2021-02-24 20:16:54 +01:00
Max Kellermann
34f735890e output/snapcast: remove obsolete TODO comment 2021-02-24 17:05:14 +01:00
Max Kellermann
f08810b202 output/snapcast: add missing #ifdef HAVE_ZEROCONF 2021-02-24 17:04:15 +01:00
Max Kellermann
7a68775e6c output/snapcast: Zeroconf support 2021-02-24 17:03:30 +01:00
Max Kellermann
e4fccc85c8 Main: move Zeroconf to the I/O thread
This will allow using Zeroconf in output plugins (preparing for
Snapcast with Zeroconf).
2021-02-24 16:29:33 +01:00
Max Kellermann
2efa142ec9 output/init: use the real-time I/O thread only for the ALSA plugin 2021-02-24 16:09:11 +01:00
Max Kellermann
29b49dd630 zeroconf/{bonjour,avahi}: pass service_type as parameter 2021-02-24 15:11:11 +01:00
Max Kellermann
9d6bf7e720 test/run_avahi: refactor to RunZeroconf (both avahi and bonjour) 2021-02-24 15:09:10 +01:00
Max Kellermann
5f34508aae zeroconf/Glue: move code to the ZeroconfHelper constructor 2021-02-24 15:09:10 +01:00
Max Kellermann
2d8ecd561b zeroconf: return a publisher object 2021-02-24 15:09:10 +01:00
Max Kellermann
2059195ae9 zeroconf: add dependency on event_dep 2021-02-24 15:09:10 +01:00
Max Kellermann
d89856f77b zeroconf/avahi/Helper: make class SharedAvahiClient final 2021-02-24 15:09:10 +01:00
Max Kellermann
975d5be046 zeroconf/avahi/Init: return a std::unique_ptr<AvahiHelper> 2021-02-24 14:41:37 +01:00
Max Kellermann
b01ef1b9a6 zeroconf/Bonjour: return a std::unique_ptr<BonjourHelper> 2021-02-24 14:25:06 +01:00
Max Kellermann
ceb76b6a82 zeroconf/Bonjour: pass a context pointer to the callback 2021-02-24 14:18:35 +01:00
Max Kellermann
a7e697b588 zeroconf/Bonjour: add const 2021-02-24 14:18:17 +01:00
Max Kellermann
3ecd918442 zeroconf/Bonjour: move the DNSServiceRegister() call to the constructor 2021-02-24 14:17:59 +01:00
Max Kellermann
4fbdb3a2d5 zeroconf/Bonjour: convert the callback function to a method 2021-02-24 14:15:26 +01:00
Max Kellermann
0157643667 zeroconf/Glue: add noexcept 2021-02-24 14:15:26 +01:00
Max Kellermann
fe741bd767 zeroconf/Glue: allow ZeroconfInit() to throw 2021-02-24 14:15:04 +01:00
Max Kellermann
06b9bdba2c zeroconf/Bonjour: disallow copying 2021-02-24 13:53:36 +01:00
Max Kellermann
bd0aa74bdd zeroconf/Bonjour: rename class BonjourMonitor to BonjourHelper 2021-02-24 13:53:35 +01:00
Max Kellermann
47461df59c zeroconf/Bonjour: don't call DNSServiceRefDeallocate() if DNSServiceRegister() fails
According to
https://developer.apple.com/documentation/dnssd/1804733-dnsserviceregister
the DNSServiceRef is initialized only if DNSServiceRegister() returns
kDNSServiceErr_NoError.  The faulty error handling code could
therefore crash.
2021-02-24 13:49:03 +01:00
Max Kellermann
04d5588fe5 zeroconf/Zeroconf*: drop prefix from file names 2021-02-24 13:33:59 +01:00
Max Kellermann
40d061621b zeroconf/Avahi: remove useless log messages 2021-02-24 13:33:58 +01:00
Max Kellermann
a312629aad zeroconf: pass global port to init function 2021-02-24 06:40:26 +01:00
Max Kellermann
d527d4b530 zeroconf/avahi/Publisher: new class, replacing lots of code from ZeroconfAvahi.cxx 2021-02-23 22:07:57 +01:00
Max Kellermann
978d2638d8 zeroconf/avahi/Client: new class, replacing lots of code from ZeroconfAvahi.cxx 2021-02-23 21:53:07 +01:00
Max Kellermann
cfcafdf822 zeroconf/avahi: add class AvahiGlue 2021-02-23 21:53:00 +01:00
Max Kellermann
07865d0707 zeroconf/avahi/Poll: move to namespace Avahi 2021-02-23 21:41:16 +01:00
Max Kellermann
1ac16516a1 event/TimerList: add option to avoid the Boost dependency 2021-02-22 23:35:16 +01:00
Max Kellermann
75e8795e3f util/IntrusiveList: add method insert() 2021-02-22 23:32:51 +01:00
Max Kellermann
4912466d50 util/IntrusiveList: add method erase() 2021-02-22 23:32:47 +01:00
Max Kellermann
664674913e event/Loop: include cleanup 2021-02-22 23:32:39 +01:00
Max Kellermann
31e3658823 Merge branch 'v0.22.x' 2021-02-22 23:25:07 +01:00
Max Kellermann
abd416735d output/snapcast: implement SendTag() 2021-02-22 23:20:56 +01:00
Max Kellermann
6090bd2095 lib/yajl/Gen: new class 2021-02-22 23:12:08 +01:00
Max Kellermann
1777592ec0 lib/yajl/Handle: fix API documentation 2021-02-22 22:56:52 +01:00
Max Kellermann
8e8fbe14b1 output/snapcast: implement Drain() 2021-02-22 22:49:32 +01:00
Max Kellermann
a8a39b6a38 output/snapcast: queue chunks 2021-02-22 22:41:31 +01:00
Max Kellermann
f84cb6de5e output/snapcast/client: remove obsolete TODO comment
See commit dfc67c45c7
2021-02-22 22:39:32 +01:00
Max Kellermann
dfc67c45c7 output/snapcast: calculate the latency for TIME responses 2021-02-22 21:57:20 +01:00
Max Kellermann
e875da5d38 output/snapcast/protocol: swap "received" and "sent"
Snapcast's protocol documentation is wrong, see
https://github.com/badaix/snapcast/pull/811
2021-02-22 21:42:42 +01:00
Max Kellermann
9b9522e3f5 zeroconf/avahi/Poll: rename internal variables 2021-02-22 15:01:01 +01:00
Max Kellermann
87963685fb zeroconf/avahi/Poll: use C++11 initializer 2021-02-22 15:00:20 +01:00
Max Kellermann
0405a57f26 zeroconf/avahi/Poll: make EventLoop the first parameter 2021-02-22 14:52:21 +01:00
Max Kellermann
f29c69d6a9 zeroconf/avahi/Poll: rename timer to event 2021-02-22 14:39:28 +01:00
Max Kellermann
7ec4de841e zeroconf/avahi/Poll: add constexpr 2021-02-22 14:34:32 +01:00
Max Kellermann
1f08d2d03c zeroconf/avahi/Poll: add noexcept 2021-02-22 14:31:37 +01:00
Max Kellermann
c1a695d1ac zeroconf/avahi/Poll: add method GetEventLoop() 2021-02-22 14:31:10 +01:00
Max Kellermann
ec05056e38 zeroconf/avahi/Poll: forbid copying 2021-02-22 14:26:08 +01:00
Max Kellermann
c0b9339d31 zeroconf/AvahiPoll: move to lib/avahi/ 2021-02-22 14:24:00 +01:00
Max Kellermann
6eba621045 decoder/ffmpeg: fix build problem with FFmpeg 3.4
Regression by commit a22d1c88d7

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1097
2021-02-22 13:36:46 +01:00
Max Kellermann
a9ad8fa505 decoder/ffmpeg: move code to IsSeekable(AVFormatContext) 2021-02-22 13:33:25 +01:00
Max Kellermann
00a1731085 Merge branch 'timeout_in_second' of git://github.com/mxjeff/MPD 2021-02-20 20:11:38 +01:00
kaliko
6e3da00874 MPD_TIMEOUT is in seconds
At least I believe libmpdclient is reading env. var. as second:
https://github.com/MusicPlayerDaemon/libmpdclient/blob/master/src/settings.c#L142

ncmpc manual also mentions MPD_TIMEOUT being is second.
2021-02-20 15:22:18 +01:00
kaliko
38df01b266 Add password use with MPD_HOST 2021-02-20 15:21:15 +01:00
Max Kellermann
c729f16dcd song/DetachedSong: copy the AudioFormat from LightSong
Enables the "Format" row in "playlistinfo" responses.

https://github.com/MusicPlayerDaemon/MPD/issues/1094
2021-02-18 22:16:11 +01:00
Max Kellermann
81d0c04ed4 song/DetachedSong: add noexcept 2021-02-18 22:01:52 +01:00
Max Kellermann
0924b63e10 event/TimerWheel: add empty flag to optimize a common case 2021-02-17 19:52:45 +01:00
Max Kellermann
ce6afe9379 output/httpd/Page: convert to type alias on AllocatedArray 2021-02-17 18:01:27 +01:00
Max Kellermann
6f04b2230a output/httpd/Page: use std::byte 2021-02-17 17:54:38 +01:00
Max Kellermann
8d90b831e1 output/snapcast/Timestamp: drop static 2021-02-17 14:39:20 +01:00
Max Kellermann
d4710604c4 doc/plugins.rst: fix typo 2021-02-17 14:39:06 +01:00
Max Kellermann
85427826aa increment version number to 0.22.7 2021-02-17 14:36:06 +01:00
Max Kellermann
9c8da03c5c output/snapcast: new output plugin
New experimental code, first draft - it works, but there's a lot left
to do.  Just look at all the TODO comments.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/975
2021-02-17 14:25:23 +01:00
Max Kellermann
85adefd9a4 encoder/wave: remove constexpr because memcpy() is not allowed 2021-02-17 14:19:02 +01:00
Max Kellermann
22804cfbe8 Merge branch 'patch-2' of git://github.com/fschlich/MPD 2021-02-17 07:25:06 +01:00
Florian Schlichting
25e0a90402 fix typo in protocol.rst
Exmaple -> Example
2021-02-17 03:18:23 +01:00
Max Kellermann
8a4b88a59d encoder/wave: use the structs from RiffFormat.hxx 2021-02-16 19:50:52 +01:00
Max Kellermann
d2371af120 encoder/wave: add static_assert on sizeof(WaveHeader) 2021-02-16 19:50:46 +01:00
Max Kellermann
aa2e1bb310 encoder/wave: refactor fill_wave_header() to function 2021-02-16 19:50:43 +01:00
Max Kellermann
6153fca4fc tag/RiffFormat: add struct RiffFmtChunk 2021-02-16 19:50:40 +01:00
Max Kellermann
f090af0a22 tag/RiffFormat: add static_asserts on sizeof() 2021-02-16 19:50:25 +01:00
Max Kellermann
58f420fdca tag/RiffFormat: use CamelCase 2021-02-16 19:24:51 +01:00
Max Kellermann
ded2b31fbc tag/Riff: split into RiffId3.?xx and RiffFormat.hxx 2021-02-16 19:23:01 +01:00
Max Kellermann
75c8d2235b util/ByteOrder: add classes PackedBE16, PackedLE16, PackedLE32 2021-02-16 17:37:25 +01:00
Max Kellermann
f679961564 Merge tag 'v0.22.6'
release v0.22.6
2021-02-16 13:58:47 +01:00
Max Kellermann
938728820b release v0.22.6 2021-02-16 13:56:14 +01:00
Max Kellermann
80531ef8d8 db/simple: fix ExportedSong move constructor for non-owning sources
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
2021-02-16 13:52:25 +01:00
Max Kellermann
a91fba6a3d increment version number to 0.22.6 2021-02-16 13:47:33 +01:00
Max Kellermann
471c37be59 queue/PlaylistEdit: convert start/end parameters to RangeArg 2021-02-15 22:51:09 +01:00
Max Kellermann
157ddcbab1 protocol/RangeArg: add methods ClipRelaxed(), CheckClip(), CheckAdjustEnd() 2021-02-15 22:50:49 +01:00
Max Kellermann
ab160aa359 queue/PlaylistEdit: check "current>=0" before updating it 2021-02-15 22:50:37 +01:00
Max Kellermann
ecc07e4e98 Merge tag 'v0.22.5'
release v0.22.5
2021-02-15 22:50:16 +01:00
Max Kellermann
f8be403c34 release v0.22.5 2021-02-15 21:18:18 +01:00
Max Kellermann
28a5cdf319 android/meson.build: update the SDK platform to 29
Needed for `requestLegacyExternalStorage` (commit ca02fb7782).
2021-02-15 21:17:26 +01:00
Max Kellermann
6b1d264b35 command/queue: better error message for open-ended range with "move"
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
2021-02-15 20:57:22 +01:00
Max Kellermann
a6c10e9a1c protocol/ArgParser: check for invalid ranges
Catch errors like that early, before invalid ranges get passed to
internal MPD subsystems.
2021-02-15 20:55:30 +01:00
Max Kellermann
19a46064e9 protocol/RangeArg: add methods IsWellFormed(), IsEmpty(), HasAtLeast(), Count() 2021-02-15 20:54:51 +01:00
Max Kellermann
b57eeaa720 protocol/RangeArg: add static method Single() 2021-02-15 20:29:37 +01:00
Max Kellermann
ad059d5804 protocol/RangeArg: add method IsOpenEnded() 2021-02-15 20:29:35 +01:00
Max Kellermann
6e1940e930 protocol/RangeArg: add static method OpenEnded() 2021-02-15 20:29:34 +01:00
Max Kellermann
103194e32d protocol/RangeArg: add missing noexcept 2021-02-15 19:56:02 +01:00
Naglis Jonaitis
cbc830fd65 doc/client.rst: fix typo 2021-02-15 20:23:32 +02:00
Shen-Ta Hsieh
481c330c17 src/output: Set thread name for Wasapi output thread 2021-02-15 17:51:49 +01:00
Shen-Ta Hsieh
7ef489e057 src/win32: run clang-format 2021-02-15 17:50:51 +01:00
Shen-Ta Hsieh
d9e5d5ff5b src/win32: Add error message for NO_ERROR 2021-02-15 17:45:25 +01:00
Max Kellermann
ca02fb7782 android/AndroidManifest.xml: enable requestLegacyExternalStorage
This is a workaround for the new scoped storage design in Android 11:

 https://developer.android.com/about/versions/11/privacy/storage

This needs a proper solution eventually, but this quick fix will do
until we change "targetSdkVersion" to 30.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1061
2021-02-15 17:43:05 +01:00
Max Kellermann
d4d06da2f8 db/simple: fix dangling LightSong::tag reference in moved ExportedSong
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
2021-02-15 17:38:37 +01:00
Max Kellermann
efde78db77 output/Thread: skip drain calls if there is no data to be played
Keep track of whether there is data being played, and don't call
AudioOutput::Drain() after Cancel() has been called already.
2021-02-15 16:39:13 +01:00
Max Kellermann
f1b8bcd6b2 output/pulse: don't drain if stream is suspended or corked
In this state, we can't make any progress.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1084
2021-02-15 16:07:16 +01:00
Max Kellermann
c2bc3704e1 output/pulse: move code to virtual method Drain()
Drain only if it was requested explicitly.
2021-02-15 15:59:54 +01:00
Max Kellermann
def120aca4 output/pulse: eliminate the pause field
It is useless, because we're always checking pa_stream_is_corked().
2021-02-15 15:59:46 +01:00
Max Kellermann
6d2b09ac2b doc/developer.rst: update branch names 2021-02-15 13:41:46 +01:00
Max Kellermann
98a9f81d61 doc/client.rst: new chapter about client development 2021-02-15 13:26:25 +01:00
Max Kellermann
78b43a9930 doc/protocol.rst: document add on local socket
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1022
2021-02-15 13:00:18 +01:00
AndriiZ
f5460b35a3 Add cacert option for Curl plugin. Allows to set cacert for curl lib ()
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
2021-02-13 13:49:15 +02:00
Max Kellermann
3456b1e50d use std::size_t 2021-02-12 18:39:28 +01:00
Max Kellermann
fe6abe1750 zlib/Error: add noexcept 2021-02-12 18:37:32 +01:00
Max Kellermann
6cdb3ff21e use [[gnu::pure]] instead of gcc_pure
This is semi-standard and doesn't require the util/Compiler.h header.
2021-02-12 18:34:16 +01:00
Max Kellermann
01af2778ab time/ISO8601: throw std::invalid_argument on error
Throwing std::runtime_error was slightly wrong.
2021-02-12 18:31:56 +01:00
Max Kellermann
ad03c70753 event/TimerWheel: workaround for GCC9 bug 2021-02-12 18:29:02 +01:00
Max Kellermann
7fe0095fa7 util/IntrusiveList: add noexcept to defaulted constructor 2021-02-11 21:22:15 +01:00
Max Kellermann
a4b236348f Merge branch 'v0.22.x' 2021-02-07 22:04:07 +01:00
Max Kellermann
da5ff779c6 python/build/libs.py: enable CURL/schannel support on Windows
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1031
2021-02-07 21:58:08 +01:00
Max Kellermann
e7da5b104d archive/iso9660: another fix for unaligned reads
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
2021-02-07 21:41:51 +01:00
Max Kellermann
aa40aae5bd doc/user.rst: add section about profiling MPD 2021-02-07 21:38:24 +01:00
Max Kellermann
4be76f3c8f archive/iso9660: check "skip==0" before doing optimized large read
After a Seek() to an odd offset, some data needs to be skipped from
the start of the block, and reading right into the given buffer
doesn't work.
2021-02-07 21:38:13 +01:00
Max Kellermann
c58c53293c test/run_input: add option --seek 2021-02-07 21:20:17 +01:00
Max Kellermann
8695a2806a test/run_input: document more options 2021-02-07 21:17:10 +01:00
vkostas
a59f1b21a6 Fix: Separate Conductor from Performer
Conductor was incorrectly saved to Performer tag in MPD database
2021-02-07 20:45:01 +01:00
Max Kellermann
5a16e3ffa3 event/TimerWheel: optimized container for CoarseTimerEvent 2021-02-05 18:24:25 +01:00
Max Kellermann
d1957b83c8 event/Chrono: add type alias TimePoint 2021-02-05 18:19:23 +01:00
Max Kellermann
1b4fd74575 event/TimerEvent: rename to FineTimerEvent
... and make TimerEvent a type alias for FineTimerEvent (i.e. swap
names).
2021-02-05 18:18:05 +01:00
Max Kellermann
def962b6cb event/{Coarse,Fine,Far}TimerEvent: aliases for TimerEvent
Preparing for a variant of TimerEvent with coarse 1-second
granularity, but cheaper (with a timer wheel).
2021-02-05 18:16:05 +01:00
Max Kellermann
e802f1f61a event/Loop: move TimerSet to separate class 2021-02-05 18:09:21 +01:00
Max Kellermann
271b287356 event/TimerEvent: assign due in Schedule() 2021-02-05 17:57:05 +01:00
Max Kellermann
2a30acd99c event/Loop: use [[gnu::pure]] 2021-02-05 17:55:33 +01:00
Max Kellermann
a8e70f18fd event/*: use using instead of typedef 2021-02-05 17:54:16 +01:00
Max Kellermann
ddd9f20a0b fs/io/GunzipReader: document that the constructor throws 2021-02-04 17:29:00 +01:00
Max Kellermann
f4a5d671fe util/{Const,Writable}Buffer: include cleanup 2021-02-04 17:27:48 +01:00
Richard Backhouse
c72006dbcc zeroconf/ZeroconfBonjour: Cleanup formatting from previous commit 2021-01-23 06:13:05 -05:00
Richard Backhouse
06fe30e2bd zeroconf/ZeroconfBonjour: Fix compile errors resulting from "refactor to SocketEvent" and reenable bonjour for darwin build 2021-01-23 06:06:49 -05:00
Max Kellermann
08e76815ba io/FileDescriptor: use std::byte 2021-01-22 12:50:16 +01:00
Max Kellermann
33ac3eb551 lib/curl/Easy: add methods SetVerify{Host,Peer}() 2021-01-22 12:34:04 +01:00
Max Kellermann
d56a51cb5e Merge branch 'v0.22.x' 2021-01-21 22:28:11 +01:00
Max Kellermann
9e2d09dabc net/SocketError: add syscall specific check functions
Fixes Windows compatibility.
2021-01-21 22:05:21 +01:00
Max Kellermann
2719f62feb net/SocketError: relicense to BSD-2 2021-01-21 21:31:02 +01:00
Max Kellermann
065a0c09f8 fs/io/StdioOutputStream: include cleanup 2021-01-21 21:13:40 +01:00
Max Kellermann
04731fb7cc util/StringPointer: add operator==(std::nullptr_t) 2021-01-21 21:08:52 +01:00
Max Kellermann
12ff5a547f fs/io/FileOutputStream: add noexcept 2021-01-21 21:04:19 +01:00
Max Kellermann
9b2eb74f95 util/AllocatedString: fix operator= parameter type 2021-01-21 20:44:07 +01:00
Max Kellermann
84084baa65 util/AllocatedString: remove wrong std:: prefix 2021-01-21 20:16:32 +01:00
Max Kellermann
3bc45fbf68 util/AllocatedString: remove Null(), IsNull() 2021-01-21 20:12:05 +01:00
Max Kellermann
36168a24f5 util/AllocatedString: support casting a nulled instance to string_view 2021-01-21 20:06:01 +01:00
Max Kellermann
5e67443a1a util/{Const,Writable}Buffer: always enable assertions 2021-01-21 20:04:00 +01:00
Max Kellermann
17858143b3 util/{Const,Writable}Buffer: enable constexpr on more methods 2021-01-21 20:03:53 +01:00
Max Kellermann
c44a7b2705 util/AllocatedArray: add operator=(nullptr) 2021-01-21 20:03:38 +01:00
Max Kellermann
0ded23591b util/AllocatedString: add operator=() 2021-01-21 20:02:52 +01:00
Max Kellermann
c1a7aa652d util/AllocatedString: replace Clone() with copy constructor 2021-01-21 20:02:41 +01:00
Max Kellermann
8d47f51399 util/AllocatedString: add const_pointer constructor 2021-01-21 18:06:10 +01:00
Max Kellermann
a81c9bfb81 util/AllocatedString: add string_view constructor
Replaces the static Duplicate() method.
2021-01-21 18:05:51 +01:00
Max Kellermann
1caf57644f util/AllocatedString: add default constructor 2021-01-21 18:05:50 +01:00
Max Kellermann
c70b63c183 util/AllocatedString: rename to BasicAllocatedString
To make things simpler, AllocatedString is now a non-template class.
2021-01-21 18:04:03 +01:00
Max Kellermann
1b89b4ef83 Merge branch 'v0.22.x' 2021-01-21 17:45:15 +01:00
Max Kellermann
234cedd6c6 increment version number to 0.22.5 2021-01-21 17:43:25 +01:00
Max Kellermann
8279cafd6d Merge tag 'v0.22.4'
release v0.22.4
2021-01-21 17:42:26 +01:00
Max Kellermann
5b946e9d95 android/AndroidManifest.xml: android release 0.22.4 2021-01-21 17:36:00 +01:00
Max Kellermann
b46ca50dcc android/AndroidManifest.xml: raise targetSdkVersion to 29
The Google overlords require me to change to 29 or else I can't upload
new releases to Google Play.

 https://developer.android.com/distribute/best-practices/develop/target-sdk
2021-01-21 17:35:59 +01:00
Max Kellermann
a0d76c3be9 release v0.22.4 2021-01-21 17:21:20 +01:00
Max Kellermann
995aafe9cc protocol: add command "binarylimit"
Increasing the protocol version to 0.22.4 to allow clients to detect
this feature.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1038
2021-01-21 17:17:10 +01:00
Max Kellermann
6e33566cee client/FileCommands: validate the given offset 2021-01-21 16:57:38 +01:00
Max Kellermann
3b3c1d466d event/FullyBufferedSocket: add method GetOutputMaxSize() 2021-01-21 16:49:38 +01:00
Max Kellermann
056ab199ab util/PeakBuffer: add method max_size() 2021-01-21 16:45:56 +01:00
Max Kellermann
eea0e084af util/PeakBuffer: use std::byte instead of std::uint8_t 2021-01-21 16:45:31 +01:00
Max Kellermann
fa82f558be util/PeakBuffer: add noexcept 2021-01-21 16:45:17 +01:00
Max Kellermann
6b555b7017 util/PeakBuffer: use std::size_t 2021-01-21 16:45:14 +01:00
Max Kellermann
dafba203e7 util/ForeignFifoBuffer: use auto 2021-01-21 16:38:32 +01:00
Max Kellermann
a5d382348e command/Request: ParseUnsigned() returns unsigned
Of course, it should do that!
2021-01-21 16:33:17 +01:00
Max Kellermann
74396448df input/curl: disable verify_peer on Android by default
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.
2021-01-21 14:55:09 +01:00
Max Kellermann
168d6257b4 python/build/libs.py: build CURL with OpenSSL support
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1059
2021-01-21 14:33:14 +01:00
Max Kellermann
014c2a82bd event/SignalMonitor: fix non-Linux build failure
Regression by commit cd4b673b6c

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1060
2021-01-21 14:05:23 +01:00
Max Kellermann
1afa33c3c7 db/simple/Song: Export() merges tags with "target"
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1048
2021-01-21 13:57:59 +01:00
Max Kellermann
3a7c9c7c84 db/simple/ExportedSong: add option to own a Tag 2021-01-21 13:52:01 +01:00
Max Kellermann
6d08e761c8 db/simple/ExportedSong: new class 2021-01-21 13:52:01 +01:00
Max Kellermann
fee282f49c SongPrint: use LightSong::GetDuration()
This properly prints the "Time"/"duration" values for songs in virtual
CUE folders.

This is loosely related to
https://github.com/MusicPlayerDaemon/MPD/issues/1048
2021-01-21 13:52:00 +01:00
Max Kellermann
07d2bc6898 util/StringView: add method SplitLast() 2021-01-21 13:20:01 +01:00
Max Kellermann
9551166f27 command/file: use %zu to format a size_t
`PRIoffset` was wrong, because it expects an `offset_type`
(i.e. `uint64_t`).  This broke on 32 bit machines where `size_t` has
32 bits.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1058
2021-01-20 20:44:47 +01:00
Max Kellermann
2a8c420cff client/Response: add printf attribute 2021-01-20 20:43:16 +01:00
Max Kellermann
ec1e04a65d Merge branch 'bugfix/1043/remove-basepath-handling' of git://github.com/PVince81/MPD into v0.22.x 2021-01-20 20:02:31 +01:00
Max Kellermann
97a2122f41 doc/mpd.conf.5.rst: updated ReplayGain website links
"The documentation for mpd.conf still links to https://replaygain.org
– according to archive.org, this domain has been defunct since
2014-09-14, shortly after got domain squatted and ever since hosts
dubious content."

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1050
2021-01-20 14:58:35 +01:00
Max Kellermann
3825175bfc python/build/ffmpeg.py: remove obsolete -no-integrated-as workaround 2021-01-19 20:17:47 +01:00
Max Kellermann
68f4be323c doc/user.rst: require Android NDK r22 2021-01-19 20:17:36 +01:00
Max Kellermann
4949cd98f3 output/sles: add missing include for assert() 2021-01-19 20:17:17 +01:00
Max Kellermann
a14ce4c7cb lib/pcre/RegexPointer: work around bogus -Wmaybe-uninitialized with GCC 11 2021-01-19 19:58:04 +01:00
Max Kellermann
85a5b7dec4 python/build/libs.py: update CURL to 7.74.0 2021-01-19 18:08:17 +01:00
Max Kellermann
153d464ce8 python/build/libs.py: update Boost to 1.75.0 2021-01-19 18:05:17 +01:00
Itai Y. Efrat
83391e2bd9 doc/protocol.rst: fix playlist(find|search)
The `{TAG} {NEEDLE}` input format documented seems to be a holdover
of pre-0.21 filters, and the commands support the new format.
2021-01-19 17:27:14 +01:00
Rosen Penev
594dfe572b clang-tidy: mark a bunch of variables constexpr
Found with cppcoreguidelines-interfaces-global-init

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2021-01-16 18:35:31 -08:00
Max Kellermann
906e82f600 event/Loop: fix assertion failure due to wrong "busy" value
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.
2021-01-12 17:28:42 +01:00
Max Kellermann
bcb7e954e9 net/Resolver: add simple getaddrinfo() wrapper 2021-01-12 15:43:26 +01:00
Max Kellermann
866c87c65e net/ToString: include cleanup 2021-01-12 12:22:44 +01:00
Max Kellermann
4ba36d7cb9 net/SocketError: relicense to BSD-2 2021-01-11 22:31:46 +01:00
Max Kellermann
13f8a912e3 event/Loop: simplify wake_event initializer 2021-01-11 20:14:20 +01:00
Max Kellermann
51f110a990 system/EventPipe: use class Unique{Socket,File}Descriptor 2021-01-11 17:51:22 +01:00
Max Kellermann
17eae74c1c system/EventFD: Get() returns FileDescriptor 2021-01-11 17:38:30 +01:00
Max Kellermann
cd4b673b6c event/WakeFD: convert macro to class with a GetSocket() method 2021-01-11 17:02:54 +01:00
Ethan Halsall
0d606c743b add additional opus encoder options 2021-01-09 22:04:00 -06:00
Vincent Petry
ec0d3ac95d Remove relative path handling which was not needed
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>
2021-01-08 16:50:27 +01:00
Max Kellermann
81ea749248 Merge branch 'v0.22.x' 2021-01-05 13:11:29 +01:00
Max Kellermann
e99f6b5b38 Merge branch 'bugfix/1039/fix-webdav' of git://github.com/PVince81/MPD into v0.22.x
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1039
2021-01-05 13:09:15 +01:00
Vincent Petry
74b2fc7fdc Use uri_has_scheme for Webdav response href
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>
2021-01-05 12:04:08 +01:00
Vincent Petry
216f62ea14 Webdav href in response can be relative
Fixed Webdav base path stripping in cases where href is a relative path.

Signed-off-by: Vincent Petry <PVince81@yahoo.fr>
2021-01-04 21:50:03 +01:00
Vincent Petry
b7d0001390 Fix parsing propstat blocks
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>
2021-01-04 21:49:38 +01:00
Vincent Petry
687788e4d3 Fix Webdav storage PROPFIND request
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>
2021-01-04 14:28:42 +01:00
Max Kellermann
e009ad1a72 thread/Id: relicense to BSD-2 2021-01-03 19:25:20 +01:00
Max Kellermann
abbd980671 Merge branch 'v0.22.x' 2021-01-01 19:59:15 +01:00
Max Kellermann
5348f8c9c8 copyright year 2021 2021-01-01 19:54:28 +01:00
Max Kellermann
5a4ebf8291 doc/protocol.rst: document that tag changed trigger "player" idle event 2020-12-18 20:41:43 +01:00
Itai Y. Efrat
7ae3664c91 doc/protocol.rst: fix MPD version on oneshot 2020-12-16 19:36:16 +02:00
Itai Y. Efrat
1caed3e390 doc/protocol.rst: fix mistake in footnotes 2020-12-16 19:06:47 +02:00
Max Kellermann
937da63ba6 util/StringView: add {Starts,Ends}With(char) 2020-12-15 17:04:39 +01:00
Max Kellermann
1f312b2e42 curl/Handler: disallow OnData() to throw
This eliminates some complexity from class CurlRequest.
2020-12-15 17:03:24 +01:00
Max Kellermann
1e3089ffb7 curl/Request: move struct Pause to class CurlResponseHandler 2020-12-15 17:01:18 +01:00
Max Kellermann
5d7ff150dd curl/Request: add more wrapper methods 2020-12-15 16:56:20 +01:00
Max Kellermann
c767501c12 Merge branch 'v0.22.x' 2020-12-15 14:11:06 +01:00
EdJoPaTo
7adb907a55 doc/protocol.rst: ensure all commands have targets 2020-12-15 14:10:28 +01:00
EdJoPaTo
00602d28a4 doc/protocol.rst: ensure all commands have targets 2020-12-15 13:49:57 +01:00
Max Kellermann
7a56837141 odbus/Watch: support DBUS_WATCH_{ERROR,HANGUP} 2020-12-14 15:10:19 +01:00
Max Kellermann
ed1caffc79 odbus/Watch: use SocketEvent::ReleaseSocket() to allow another Open() 2020-12-14 15:10:15 +01:00
Max Kellermann
65473b5113 lib/dbus/FilterHelper: new class 2020-12-14 15:07:12 +01:00
Max Kellermann
178d115ccb lib/dbus/Glue: add noexcept 2020-12-14 13:19:51 +01:00
kaliko
af2896547a doc/protocol.rst: Add missing "originaldate" to the list of supported tags 2020-12-14 13:03:30 +01:00
Max Kellermann
10e5b0759c lib/dbus/Glue: relicense to BSD-2 2020-12-14 13:02:37 +01:00
arcnmx
0a81e462db event/SocketEvent: remove FD before closing socket
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]
2020-12-04 10:32:46 +01:00
Max Kellermann
5cbbe8ae2e event/TimerEvent: update API documentation 2020-12-04 09:57:19 +01:00
Max Kellermann
00fafa16c7 event/SocketEvent: remove assert(), reduce header dependencies 2020-12-04 09:56:28 +01:00
Max Kellermann
cea8db7eaa event/SocketEvent: add comment 2020-12-04 09:55:08 +01:00
Max Kellermann
b56c0e69e4 event/SocketEvent: add another assert() to Open() 2020-12-04 09:24:02 +01:00
Max Kellermann
b27e82e4a9 event/SocketEvent: allow Schedule() with IMPLICIT_FLAGS
Relax the API (instead of tightening it further like commit
7bc1c9925b tried to do unsuccessfully).
2020-12-04 09:17:45 +01:00
Max Kellermann
ad48834469 Revert "event/SocketEvent: add assert()"
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
2020-12-02 20:43:29 +01:00
Max Kellermann
9d6b5e2ba1 event/TimerEvent: rename IsActive() to IsPending() 2020-12-02 15:41:11 +01:00
Max Kellermann
33ba190bec event/TimerEvent: add ScheduleEarlier() 2020-12-02 15:30:37 +01:00
Max Kellermann
3783350d25 event/SocketEvent: document Dispatch() 2020-12-02 15:24:23 +01:00
Max Kellermann
173405a343 event/SocketEvent: make Dispatch() private 2020-12-02 15:14:51 +01:00
Max Kellermann
7bc1c9925b event/SocketEvent: add assert() 2020-12-02 15:12:30 +01:00
Max Kellermann
ce4c69dd95 test/util/TestException: new unit test 2020-12-02 15:09:47 +01:00
Max Kellermann
8eea825462 test/util/TestTemplateString: new unit test 2020-12-02 15:03:51 +01:00
Max Kellermann
49e1ce7c43 test/TestUtil: move to test/util/ 2020-12-02 15:02:45 +01:00
Max Kellermann
618f94f589 util/TemplateString: add StringView cast operator 2020-12-02 15:00:49 +01:00
Max Kellermann
ad2c22844c util/TemplateString: add FromLiteral() 2020-12-02 15:00:39 +01:00
Max Kellermann
b8df851414 io/FileDescriptor: use std::size_t 2020-12-02 14:56:00 +01:00
Max Kellermann
a584141cae io/Open: add flags parameter to OpenReadOnly() 2020-12-02 14:52:51 +01:00
Max Kellermann
4e88f95f94 event/Loop: move the "again" check out of the mutex scope 2020-12-01 20:29:21 +01:00
Max Kellermann
790e540c19 event/Loop: use ClockCache 2020-12-01 20:25:42 +01:00
Max Kellermann
16074c565f time/ClockCache: new library 2020-12-01 20:22:26 +01:00
Max Kellermann
2a1dd55b11 event/Loop: include cleanup 2020-12-01 20:19:40 +01:00
Max Kellermann
be20f760ab event/Loop: disallow copying 2020-12-01 20:18:33 +01:00
Max Kellermann
8050394003 event/Loop: add noexcept 2020-12-01 20:10:53 +01:00
Max Kellermann
ff8b5bc61b event/Loop: reorder methods 2020-12-01 20:09:25 +01:00
Max Kellermann
ef8797821f event/Loop: inline field initializers 2020-12-01 20:07:35 +01:00
Max Kellermann
5f2797e7cc event/Loop: add more assertions to dtor 2020-12-01 20:05:54 +01:00
Max Kellermann
e286702f4c event/Loop: rename AddDeferred() to AddDefer() 2020-12-01 17:26:39 +01:00
Max Kellermann
c58aaf545f event/IdleEvent: make a special case of DeferEvent 2020-12-01 17:14:24 +01:00
Max Kellermann
990f2dc1cf event/DeferEvent: use class IntrusiveList instead of boost::intrusive::list 2020-12-01 17:14:24 +01:00
Max Kellermann
774b4313f2 event/DeferEvent: split the thread-safe version into new class InjectEvent 2020-12-01 17:14:24 +01:00
Max Kellermann
1ecbc2ff0f event/DeferEvent: explicitly forbid copying 2020-12-01 17:14:24 +01:00
Max Kellermann
fd8e38f8cd event/DeferEvent: use using instead of typedef 2020-12-01 17:14:24 +01:00
Max Kellermann
e86d4db55c Merge branch 'v0.22.x' 2020-12-01 17:14:21 +01:00
Max Kellermann
d9583faf06 input/{tidal,qobus}: add missing includes for assert() 2020-12-01 17:14:11 +01:00
Max Kellermann
2788cf9330 input/tidal: add missing include for assert() 2020-12-01 17:13:13 +01:00
Max Kellermann
9420c74101 util/AllocatedArray: add nullptr constructor 2020-11-30 22:30:57 +01:00
Max Kellermann
b1bef9c21d util/AllocatedArray: add method data() 2020-11-30 22:30:28 +01:00
Max Kellermann
5b0ef7ea98 util/AllocatedArray: add types pointer, const_pointer 2020-11-30 22:30:25 +01:00
Max Kellermann
ab53c414bc util/StringView: add method SplitLast() 2020-11-30 22:29:38 +01:00
Max Kellermann
d547ace749 io/FileDescriptor: use std::size_t 2020-11-30 22:27:16 +01:00
Max Kellermann
b47e0cffdd util/TemplateString: rename CharAsString() to FromChar() 2020-11-30 22:23:28 +01:00
Max Kellermann
3af35aee9e util/TemplateString: add cast operators 2020-11-30 22:22:24 +01:00
Max Kellermann
02314ac7dd util/TemplateString: rewrite as constexpr functions
Hooray C++17!
2020-11-30 22:19:57 +01:00
Max Kellermann
e7c4e87ac4 util/TemplateString: remove unnecessary implementation for static variable
This is obsolete since C++17.
2020-11-30 22:13:13 +01:00
Max Kellermann
de58bfbb7f util/TemplateString: use std::size_t 2020-11-30 22:13:08 +01:00
Max Kellermann
0dda4c06b1 util/TemplateString: no indent after namespace 2020-11-30 22:13:04 +01:00
Max Kellermann
79fd6143ec lib/dbus/Values: use T::Traits, not T
This template was never instantiated, so the problem never occurred.
2020-11-30 22:11:18 +01:00
Max Kellermann
8f89e3f7f4 lib/dbus/Values: use using instead of typedef 2020-11-30 22:11:14 +01:00
Max Kellermann
fc01d11b8d odbus/Types: use using instead of typedef 2020-11-30 22:08:37 +01:00
Max Kellermann
0c28d8dcbe time/ISO8601: support YYYY-MM (without day of month) 2020-11-30 21:55:12 +01:00
Max Kellermann
764eaadd25 time/Math: new library 2020-11-30 21:55:05 +01:00
Max Kellermann
273771ffec net/SocketAddress: add CastTo() 2020-11-30 21:51:07 +01:00
Max Kellermann
32ce9ce919 net/IPv[46]Address: pass SocketAddress by value to Cast() 2020-11-30 21:49:07 +01:00
Max Kellermann
34a070f5a6 net/IPv[46]Address: add Cast(const sockaddr_in&) 2020-11-30 21:49:02 +01:00
Danilo Spinella
92bfdffa42 lib/ffmpeg/Filter: Add define required for avutil 2020-11-30 20:06:21 +01:00
Max Kellermann
ac4975cd7a util/MimeType: relicense to BSD-2 2020-11-18 15:28:21 +01:00
Max Kellermann
fbbbfb9668 Merge branch 'v0.22.x' 2020-11-16 09:41:20 +01:00
Max Kellermann
38b41fc3fd filter/ffmpeg: detect the output sample format
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
2020-11-16 09:39:34 +01:00
Max Kellermann
394f69bee1 output/Control: allow copy elision (fix -Wpessimizing-move) 2020-11-15 19:55:11 +01:00
Stapper
ba5531f9dd Fixes - moveoutput: new AudioOutputControl created from copyMoving an output to a partition is now done via MultipleOutputs::AddCopy(),using a new AudioOutputControl constructor. Tags and always_on settings willpersist when moving outputs between partitions. 2020-11-15 19:47:53 +01:00
Max Kellermann
eb9f5339b6 Merge branch 'v0.22.x' into master 2020-11-11 12:43:50 +01:00
Max Kellermann
60d19b2380 doc/plugins.rst: add missing list-table declaration 2020-11-11 12:28:15 +01:00
Max Kellermann
a9714e73c8 Merge branch 'bind' of git://github.com/neheb/MPD into master 2020-11-10 16:02:34 +01:00
kaliko
004d6a3b66 doc/mpd.1.rst: Update config file documentation.
Have similar information about config file in both mpd.1 ans mpd.conf.5
2020-11-10 15:58:34 +01:00
kaliko
3e79e62c17 doc/mpd.conf.5.rst: Update mpd.conf manual
Update description with content from user manual [0].
Remove obsolete information regarding "required parameters" and log_level

[0] https://www.musicpd.org/doc/html/user.html#the-configuration-file
2020-11-10 15:58:30 +01:00
kaliko
27b69330f4 doc/mpdconf.example: add database exemples 2020-11-10 15:58:10 +01:00
kaliko
6b50b67339 doc/mpdconf.example: add available log levels 2020-11-10 15:58:03 +01:00
kaliko
51ca775a1c doc/mpdconf.example: Strip trailing space, fixed typo. 2020-11-10 15:57:54 +01:00
Max Kellermann
1092882f38 decoder/dsdiff: apply padding to odd-sized chunks
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1001
2020-11-10 15:55:33 +01:00
Max Kellermann
8a7986c3bf doc/plugins.rst: add DSD spec links 2020-11-10 15:53:35 +01:00
Max Kellermann
a99bc91eb0 Merge tag 'v0.22.3' into master
release v0.22.3
2020-11-06 16:14:46 +01:00
Max Kellermann
c7bd8c663d increment version number to 0.22.4 2020-11-06 16:14:23 +01:00
Max Kellermann
f6c65cba58 release v0.22.3 2020-11-06 16:12:54 +01:00
Max Kellermann
f849b07766 storage/curl: fix nullptr dereference
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
2020-11-06 15:35:47 +01:00
Rosen Penev
071d3c71d8 clang-tidy: replace std::bind with lambdas
Found with modernize-avoid-bind

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-11-05 18:09:30 -08:00
Max Kellermann
afbcac9fb1 util/MimeType: use IterableSplitString() in ParseMimeTypeParameters() 2020-11-04 21:29:42 +01:00
Max Kellermann
51e5b56b3a playlist/registry: remove duplicate function ExtractMimeTypeMainPart()
This is the same as GetMimeTypeBase(), which has already been applied.
2020-11-04 21:20:43 +01:00
Max Kellermann
bb07fd42ce util/MimeType: migrate GetMimeTypeBase() to std::string_view 2020-11-04 21:20:03 +01:00
Max Kellermann
bab626c325 util/UriExtract: remove the query string at the beginning of uri_get_suffix() 2020-11-04 21:15:41 +01:00
Max Kellermann
2a9131498f util/UriExtract: pass std::string_view to uri_get_suffix() 2020-11-04 21:13:57 +01:00
Max Kellermann
35a232105e util/UriExtract: uri_get_suffix() returns std::string_view
No need to copy it to a buffer.
2020-11-04 21:08:26 +01:00
Max Kellermann
19dd1a25d7 {decoder,archive,playlist}/plugin: pass std::string_view to SupportsMimeType() 2020-11-04 21:00:49 +01:00
Max Kellermann
53396c0e50 Merge branch 'v0.22.x' into master 2020-11-04 20:37:25 +01:00
Max Kellermann
0b8208fe7f Merge branch 'clng11' of git://github.com/neheb/MPD into master 2020-11-04 20:34:55 +01:00
Max Kellermann
2da3cff1e8 filter/LoadChain: use the AutoConvertFilter
This adds support for input samples other than 16 bit to the FFmpeg
filter plugin.
2020-11-04 20:15:19 +01:00
Max Kellermann
0c965d0573 filter/AutoConvert: move the Filter class to TwoFilters.cxx 2020-11-04 20:15:19 +01:00
Max Kellermann
77c14692c9 filter/AutoConvert: eliminate AutoConvertFilter if possible
If no conversion is necessary, return the child Filter as-is.  This
allows removing all nullptr checks from AutoConvertFilter.
2020-11-04 20:15:19 +01:00
Max Kellermann
226eb26300 filter/ffmpeg: interleave the output AVFrame
If the FFmpeg filter outputs planar data, interleave it, just like the
FFmpeg decoder plugin does.
2020-11-04 20:15:19 +01:00
Max Kellermann
2d606fa989 decoder/ffmpeg: move code to lib/ffmpeg/Interleave.cxx
To be reused by the FFmpeg filter plugin.
2020-11-04 20:15:19 +01:00
Max Kellermann
7a0342c8bb decoder/ffmpeg: use AVFrame fields instead of AVCodecContext fields 2020-11-04 20:06:45 +01:00
Max Kellermann
42c9d765cf lib/ffmpeg/Buffer: add missing include 2020-11-04 20:06:41 +01:00
Max Kellermann
a8a80ee689 lib/ffmpeg/Buffer: disallow copying 2020-11-04 19:51:21 +01:00
Max Kellermann
f9bdb4b0b8 lib/ffmpeg/Buffer: add noexcept 2020-11-04 19:50:38 +01:00
Max Kellermann
9332527872 lib/ffmpeg/{Buffer,Time}: remove obsolete "#undef SampleFormat"
This compatibility macro has been removed from FFmpeg long ago.
2020-11-04 19:50:33 +01:00
Max Kellermann
84f772357e filter/convert: convert_filter_new() returns std::unique_ptr 2020-11-04 16:47:11 +01:00
Max Kellermann
f2b9785a67 filter/chain: pass std::string_view to filter_chain_append() 2020-11-04 16:37:53 +01:00
Max Kellermann
eeaec99c59 filter/LoadChain: use IterableSplitString() 2020-11-04 16:36:11 +01:00
Max Kellermann
b0002e3b73 filter/chain: copy the child name
filter_chain_parse() passes a temporary string pointer which results
in a use-after-free in the PreparedChainFilter::Child::Open() error
message.
2020-11-04 16:34:38 +01:00
Max Kellermann
27c589da97 filter/chain: remove unused field ChainFilter::Child::name 2020-11-04 16:26:50 +01:00
Max Kellermann
6484af472b increment version number to 0.22.3 2020-11-04 16:14:40 +01:00
Max Kellermann
92a218b7a9 playlist/registry: add option "as_directory"
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.
2020-11-04 16:13:12 +01:00
Max Kellermann
d69a1f98af doc/plugins.rst: more markup 2020-11-04 16:11:26 +01:00
Max Kellermann
23a6f62ea3 doc/user.rst: fix typo 2020-11-04 15:59:40 +01:00
Max Kellermann
e0d3ca71b3 meson.build: switch to C11
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.
2020-11-04 14:38:58 +01:00
Max Kellermann
4f40b9f7cf meson.build: disable ld.so lazy binding and enable relro
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.
2020-11-04 13:43:21 +01:00
Max Kellermann
bb009daf66 playlist/registry: simplify ExtractMimeTypeMainPart() 2020-11-04 13:34:04 +01:00
Max Kellermann
3d276d50b4 event/PollBackend: use vector::push_back() instead of resize() 2020-10-30 16:35:20 +01:00
Max Kellermann
b1b731340e event/PollBackend: add Item constructor 2020-10-30 16:32:45 +01:00
Max Kellermann
b9b02b4ff2 event/PollBackend: use unordered_map::find() instead of operator[]
The latter creates a new object, but we know that the key already
exists.
2020-10-30 16:25:41 +01:00
Max Kellermann
ab5d23da11 event/PollBackend: use unordered_map::emplace() in Add() 2020-10-30 16:24:32 +01:00
Max Kellermann
0554fe3652 event/PollBackend: use std::size_t 2020-10-30 16:09:29 +01:00
Max Kellermann
b0282fe36f event/PollGroupWinSelect: add Item constructor 2020-10-30 16:07:23 +01:00
Max Kellermann
69b45e693b event/WinSelect: use unordered_map::find() instead of operator[]
The latter creates a new object, but we know that the key already
exists.
2020-10-30 16:05:25 +01:00
Max Kellermann
9e97acc28d event/WinSelect: merge duplicate code into ApplyReady() 2020-10-30 15:55:23 +01:00
Max Kellermann
b1e446a931 event/WinSelect: add missing const to deleted copy ctor/operator 2020-10-30 15:45:29 +01:00
Max Kellermann
938319cd44 event/WinSelect: reorder method prototypes 2020-10-30 15:45:12 +01:00
Max Kellermann
fee29001fa event/WinSelect: use unordered_map::emplace() in Add()
This allow using erase() with iterator, without a key lookup.
2020-10-30 15:32:11 +01:00
Max Kellermann
6d894a1806 event/WinSelect: use SOCKET as std::unordered_map key 2020-10-30 15:25:09 +01:00
Rosen Penev
f1fc5d79ca clang-tidy: convert to all/any_of
Found with readability-use-anyofallof

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-10-28 15:51:21 -07:00
Rosen Penev
0fd2c74a66 use structured binding declarations
Shorter.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-10-28 15:41:31 -07:00
Max Kellermann
bb99cf37e3 Merge tag 'v0.22.2' into master
release v0.22.2
2020-10-28 17:33:10 +01:00
Max Kellermann
dc432f3ffa release v0.22.2 2020-10-28 17:25:33 +01:00
Max Kellermann
37710195ca meson_options.txt: disable the "smbclient" plugin by default
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
2020-10-28 17:21:27 +01:00
Max Kellermann
7b9295ff99 lib/yajl/Handle: strip newlines from error messages
Closes https://github.com/MusicPlayerDaemon/MPD/issues/981
2020-10-28 16:06:52 +01:00
Max Kellermann
5f61d440eb lib/yajl/Handle: un-inline the throwing code
Reduces header dependencies.
2020-10-28 16:02:14 +01:00
Max Kellermann
6bc73a9ebe util/FormatString: update API documentation 2020-10-28 15:48:42 +01:00
Max Kellermann
1195eb266e protocol/Ack: remove unused variable ack_domain 2020-10-28 15:47:05 +01:00
Max Kellermann
3562a3e51e Main: save the state_file on shutdown
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
2020-10-28 15:29:47 +01:00
Max Kellermann
7c47fe746c event/Loop: AbandonFD() unlinks the SocketEvent
Fixes use-after-free bugs causing assertion failures at shutdown,
because all "abandoned" SocketEvents are still in the linked list.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/986
Closes https://github.com/MusicPlayerDaemon/MPD/issues/987
2020-10-28 15:01:32 +01:00
Max Kellermann
65a1c4a016 event/Loop: pass SocketEvent& to AbandonFD() 2020-10-28 14:59:28 +01:00
Max Kellermann
46418d0f2d event/ServerSocket: remove obsolete API documentation 2020-10-28 14:52:31 +01:00
Max Kellermann
bbfa6fe632 db/simple: purge songs for unavailable decoder plugins on update 2020-10-28 14:36:20 +01:00
Max Kellermann
bf97d13d0b fs/Traits: add GetPathSuffix() 2020-10-28 14:29:46 +01:00
Max Kellermann
b5673b6333 db/simple/Directory: add pure attribute 2020-10-28 14:24:58 +01:00
Max Kellermann
ee802867df db/update/Walk: add code comments 2020-10-28 14:23:39 +01:00
Max Kellermann
ecaa51e322 db/simple: purge special directories for unavailable plugins on update 2020-10-27 19:14:31 +01:00
Max Kellermann
0779333064 db/update/Walk: adjust lamba indent 2020-10-27 19:14:31 +01:00
Max Kellermann
6f1a4a73b7 fs/Traits: add GetFilenameSuffix() 2020-10-27 19:14:31 +01:00
Max Kellermann
945ed2610a increment version number to 0.22.2 2020-10-27 18:34:39 +01:00
arcnmx
ad585e179f system/FileDescriptor: fix Duplicate result
dup2 returns new_fd on success, not 0
2020-10-20 09:32:43 -07:00
Max Kellermann
8348a1ec8f event/PollGroup: rename to PollBackend 2020-10-19 14:52:59 +02:00
Max Kellermann
c18e00daa4 event/PollGroup: move event flags to a separate header
Reduce header dependencies for SocketEvent.hxx.
2020-10-19 14:48:41 +02:00
Max Kellermann
418ba96334 event/SocketEvent: forbid copying 2020-10-18 20:07:49 +02:00
Max Kellermann
a60e782959 event/Loop: reorder assertions 2020-10-18 20:05:22 +02:00
Max Kellermann
8bab5733d7 event/Loop: add assertions 2020-10-18 20:04:16 +02:00
Max Kellermann
e3270dfd68 event/SocketEvent: use class IntrusiveList<> 2020-10-18 20:02:47 +02:00
Max Kellermann
a14997ffb8 event/Loop: manage all SocketEvents in a linked list
Not only those which are "ready".
2020-10-18 20:01:38 +02:00
Max Kellermann
dd94f97572 event/Loop: un-inline AddFD(), ModifyFD()
Prepare for adding more code here.
2020-10-18 19:58:42 +02:00
Max Kellermann
7d502fb448 event/Loop: round epoll_wait() timeout up
This implements proper rounding, amending commit dcbb9fe07c
2020-10-18 19:58:42 +02:00
Max Kellermann
3ac87bbcda io/uring/Queue: use IntrusiveList<> 2020-10-18 19:37:54 +02:00
Max Kellermann
f64799622d event/IdleEvent: use class IntrusiveList<> 2020-10-18 19:28:12 +02:00
Max Kellermann
6f0ad2b6c5 util/IntrusiveList: replacement for boost::intrusive::list 2020-10-18 19:23:34 +02:00
Max Kellermann
b5750afb24 event/IdleEvent: use auto 2020-10-18 19:23:34 +02:00
Max Kellermann
442dd5e955 event/IdleEvent: forbid copying 2020-10-18 19:23:25 +02:00
Max Kellermann
172c2ae1aa Merge tag 'v0.22.1' into master
release v0.22.1
2020-10-17 13:58:36 +02:00
Max Kellermann
d7fcaf33b9 release v0.22.1 2020-10-17 13:56:12 +02:00
Max Kellermann
6a65b4c305 lib/nfs/patches: disable the snprintf->sprintf_s alias
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).
2020-10-17 13:56:02 +02:00
Max Kellermann
4f0e0af319 Merge branch 'v0.22.x' into master 2020-10-16 19:02:03 +02:00
Max Kellermann
cb382b1e7d event/PollGroupWinSelect: add missing return value
Fixes regression from commit 1473d8474f
2020-10-16 19:02:00 +02:00
Max Kellermann
a163beee69 python/build/libs.py: update CURL to 7.73.0 2020-10-16 18:53:47 +02:00
Max Kellermann
31268ad7cd decoder/opus: fix track/album ReplayGain fallback
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
2020-10-16 18:45:18 +02:00
Max Kellermann
a0d43dd87f decoder/opus: submit output_gain even if there is no OpusTags packet 2020-10-16 18:41:16 +02:00
Max Kellermann
1db533c8cf decoder/opus: move formula to EbuR128ToReplayGain() 2020-10-16 18:39:29 +02:00
Max Kellermann
78ee663660 decoder/opus: move comment to output_gain field 2020-10-16 18:30:51 +02:00
Max Kellermann
c32a809d38 decoder/opus: convert field output_gain to float 2020-10-16 18:28:57 +02:00
Max Kellermann
871bf3b88f command: add command "getvol"
Closes https://github.com/MusicPlayerDaemon/MPD/issues/979
2020-10-16 17:51:51 +02:00
Max Kellermann
08360e401d meson.build: increment protocol version to 0.23 2020-10-16 17:46:47 +02:00
Max Kellermann
b611b1824a event/Loop: move code to Wait() 2020-10-15 20:21:00 +02:00
Max Kellermann
1473d8474f event/PollGroup: ReadEvents() returns PollResult 2020-10-15 20:15:09 +02:00
Max Kellermann
0ecc3394c3 Merge branch 'v0.22.x' into master 2020-10-15 20:14:36 +02:00
Max Kellermann
725985379a event/SocketEvent: add ScheduleImplicit(), Is{Read,Write}Pending() 2020-10-15 17:01:30 +02:00
Max Kellermann
8849b9b62c event/SocketEvent: move Abandon() up 2020-10-15 16:59:45 +02:00
Max Kellermann
caa2611ad5 event/SocketEvent: add Abandon() 2020-10-15 16:57:55 +02:00
Max Kellermann
f8ff597963 event/SocketEvent: document Close() 2020-10-15 16:55:31 +02:00
Max Kellermann
ff6e434caf event/SocketEvent: rename Steal() to ReleaseSocket() 2020-10-15 16:54:33 +02:00
Max Kellermann
95bb12880d net/UniqueSocketDescriptor: add noexcept 2020-10-15 16:46:29 +02:00
Max Kellermann
257196664a net/SocketAddress: add missing include 2020-10-15 16:45:50 +02:00
Max Kellermann
643bf95366 util/OffsetPointer: use std::ptrdiff_t 2020-10-15 16:41:39 +02:00
Max Kellermann
36a187da39 util/Cast: include cleanup 2020-10-15 16:40:26 +02:00
Max Kellermann
fec80f2835 util/Cast: use std::ptrdiff_t 2020-10-15 16:40:18 +02:00
Max Kellermann
4e47653cf6 lib/curl/Global: ignore curl_multi_socket_action() errors
Keep the logging library out of this low-level libcurl wrapper.
2020-10-15 16:31:31 +02:00
Max Kellermann
c13004f985 lib/curl/Multi: add Add(), Remove(), ... 2020-10-15 16:25:57 +02:00
Max Kellermann
baba41e304 lib/curl/Global: adjust parameter name 2020-10-15 16:16:02 +02:00
Max Kellermann
d87e09a8b4 lib/dbus/ReadIter: remove obsolete GCC warning workaround
We need at least GCC 8 anyway.
2020-10-15 16:08:29 +02:00
Max Kellermann
33146ac353 lib/dbus/Watch: adjust parameter name 2020-10-15 16:06:19 +02:00
Max Kellermann
1406144210 lib/dbus/Watch: add missing include for assert() 2020-10-15 16:05:05 +02:00
Max Kellermann
bb6ab67175 output/osx: fix several -Wdouble-promotion warnings 2020-10-15 15:01:28 +02:00
Max Kellermann
ed3d8222d6 net/SocketAddress: include cleanup 2020-10-15 15:01:19 +02:00
Max Kellermann
bb20af8f20 util/StringStrip: use std::strlen() 2020-10-15 12:54:47 +02:00
Max Kellermann
9355ec44e0 util/StringStrip: use std::size_t 2020-10-15 12:53:02 +02:00
Max Kellermann
c63bd323ce util/StringCompare: use std::memcmp() 2020-10-15 12:48:33 +02:00
Max Kellermann
55db7105c5 event/SocketEvent: check/clear scheduled_flags in Close()
Fixes regression by commit 521e573be9
2020-10-14 21:08:39 +02:00
Max Kellermann
1c079e554b io/UniqueFileDescriptor: add method Release() 2020-10-14 20:50:02 +02:00
Max Kellermann
48afb68f3a event/SocketEvent: remove assert() from GetScheduledFlags()
Fixes regression by commit 7901b04c78
2020-10-14 20:50:02 +02:00
Max Kellermann
21f409d5e2 event/SocketEvent: fix grammar 2020-10-14 16:30:38 +02:00
Max Kellermann
521e573be9 event/SocketEvent: use EventLoop::AbandonFD() in Close() 2020-10-14 16:29:49 +02:00
Max Kellermann
abf9ae2dd9 event/Loop: rename Abandon() to AbandonFD() 2020-10-14 16:26:06 +02:00
Max Kellermann
9f013f7de4 event/SocketEvent: allow Close() without socket 2020-10-14 16:26:01 +02:00
Max Kellermann
7fc04fd5cd event/SocketEvent: move Dispatch() down 2020-10-14 16:21:41 +02:00
Max Kellermann
7901b04c78 event/SocketEvent: allow Cancel() without socket 2020-10-14 16:20:43 +02:00
Max Kellermann
653eea5840 event/SocketEvent: remove unnecessary initializer 2020-10-14 16:18:39 +02:00
Max Kellermann
5a4055fb08 event/SocketMonitor: refactor to SocketEvent
Similar to commits 1686f4e857 and
30a5dd267b
2020-10-14 15:54:12 +02:00
Max Kellermann
4d68a12f03 event/Loop: split the AtScopeExit()
Fixes the !HAVE_THREADED_EVENT_LOOP build.
2020-10-14 14:47:59 +02:00
Max Kellermann
0e951da64b event/Loop: add missing #ifdef 2020-10-14 14:37:29 +02:00
Max Kellermann
38dab040b3 event/Loop: add compile-time option to disable multithreading
Not for MPD, but for other applications which might want to copy its
event loop, but do not need multi-threading.
2020-10-14 14:08:38 +02:00
Max Kellermann
e9f6af61f9 event/Loop: forward-declare class {Idle,Defer}Event 2020-10-14 14:05:17 +02:00
Max Kellermann
b06c4e2711 event/{Idle,Defer}Event: use base_hook instead of member_hook
Allows forward declaration.
2020-10-14 14:04:30 +02:00
Max Kellermann
1686f4e857 event/IdleMonitor: refactor to IdleEvent
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.
2020-10-14 13:47:25 +02:00
Max Kellermann
9f57732af2 meson.build: increment version to 0.23~git
The new stable branch v0.22.x was forked off and is feature-frozen, so
the "master" branch will become the next major version eventually.
2020-10-14 12:13:12 +02:00
Max Kellermann
329382c1da event/SignalMonitor: add noexcept 2020-10-13 17:26:33 +02:00
Max Kellermann
fadc03df21 meson.build: move macros to event/Features.h 2020-10-13 16:15:52 +02:00
Max Kellermann
54ee0e28ab event/PollGroup: check _WIN32 instead of USE_WINSELECT 2020-10-13 15:27:58 +02:00
Max Kellermann
92fc53ebef event/PollGroupWinSelect: use range-based for 2020-10-12 12:44:23 +02:00
Max Kellermann
7e7a1613cf event/PollGroupWinSelect: use std::copy_n() 2020-10-12 12:40:32 +02:00
Max Kellermann
f73c4643ef event/PollGroupWinSelect: move IsEmpty() check to GetPtr() 2020-10-12 12:39:10 +02:00
Max Kellermann
8b94e8f260 event/PollGroupWinSelect: use SOCKET instead of int 2020-10-12 12:13:46 +02:00
Max Kellermann
41bc17a27f event/SocketMonitor: add ready_flags
By making each SocketMonitor keep track of its ready flags, this
removes a lot of overhead from EventLoop::RemoveFD().
2020-10-09 17:28:11 +02:00
Max Kellermann
41c0bbab13 event/SocketMonitor: don't filter out ERROR/HANGUP
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.
2020-10-08 21:16:18 +02:00
Max Kellermann
eeb96eb367 event/TimerEvent: add type alias for std::chrono::steady_clock::duration 2020-10-08 20:48:50 +02:00
Max Kellermann
ce93e58944 event/TimerEvent: use using instead of typedef 2020-10-08 20:46:18 +02:00
Max Kellermann
263b0ffdbb event/TimerEvent: use auto_unlink hook 2020-10-08 20:46:15 +02:00
Max Kellermann
22bea5c97e event/Loop: reorder includes
This just happened to break the Windows build because of the
`GetObject` macro in `windows.h`, so I added a kludge to
PollResultGeneric.hxx.
2020-10-08 20:43:21 +02:00
Max Kellermann
75802ebcc6 StateFileConfig, ...: drop obsolete out-of-class definition 2020-10-08 20:38:11 +02:00
Max Kellermann
27cc7b352d config/Data: cast to std::chrono::steady_clock::duration properly
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.
2020-10-08 20:30:33 +02:00
Max Kellermann
d64729065e config/Parser: use std::size_t 2020-10-08 20:26:39 +02:00
Max Kellermann
ab318200db config/{Data,Block}: use With() in GetUnsigned(), GetPositive() 2020-10-08 20:21:09 +02:00
Max Kellermann
947856ca8e event/Loop: forward-declare class TimerEvent 2020-10-08 17:24:32 +02:00
Max Kellermann
cd9ff9d9b0 event/TimerEvent: use base_hook instead of member_hook 2020-10-08 17:00:09 +02:00
Max Kellermann
4cd0f661d6 event/Loop: use using instead of typedef 2020-10-08 16:59:21 +02:00
Max Kellermann
bf270a5663 doc/user.rst: document io_uring 2020-10-06 19:14:44 +02:00
Max Kellermann
6e893f40e3 doc/user.rst: common startup problems 2020-10-06 19:14:18 +02:00
Max Kellermann
7690905503 doc/user.rst: remove "Question" prefix from "Common Problems" 2020-10-06 19:03:03 +02:00
Max Kellermann
6f822a6f19 doc/user.rst: remove numbers from section headers 2020-10-06 18:59:01 +02:00
Max Kellermann
ca0179b2a9 event/Loop: set the uring_initialized flag
Don't attempt to initialize the io_uring subsystem more than once.
2020-10-06 18:58:54 +02:00
Max Kellermann
6682cf749f playlist/cue/parser: use lambda to fix ambiguous overload
On Windows, there is an IsWhitespaceOrNull() overload with TCHAR, and
the compiler doesn't know which one to pass to std::find_if().
2020-10-05 21:15:10 +02:00
Max Kellermann
492607ecbe playlist/cue/parser: use StringView internally
Don't copy the input StringView.
2020-10-05 21:04:49 +02:00
Max Kellermann
e0c75da266 playlist/cue/parser: pass StringView to Feed() 2020-10-05 20:33:58 +02:00
Max Kellermann
34bb53a29f playlist/cue/parser: add noexcept 2020-10-05 20:33:50 +02:00
Max Kellermann
cb4fdac469 playlist/cue/parser: fix nullptr dereference
Closes https://github.com/MusicPlayerDaemon/MPD/issues/974
2020-10-05 20:26:42 +02:00
Max Kellermann
ac46a84391 playlist/cue/parser: fix off-by-one buffer overflow
cue_next_word() can return a pointer one past the end of the string if
the word is followed by the terminating null byte.
2020-10-05 20:26:02 +02:00
Max Kellermann
dffd5831f8 test/fuzzer: a simple fuzzer using libFuzzer
This commit adds some basic infrastructure for fuzzers, and adds a
fuzzer for the CUE sheet parser.
2020-10-05 20:25:26 +02:00
Max Kellermann
8358b34efa meson_options.txt: move "test" to a new section 2020-10-05 19:44:52 +02:00
Max Kellermann
4484d7a5c2 output/jack: implement Interrupt() 2020-10-02 11:00:04 +02:00
Max Kellermann
b80a135cf3 output/pulse: implement Interrupt() 2020-10-02 10:52:25 +02:00
Max Kellermann
4ad525d939 output/alsa: implement Interrupt()
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
2020-10-02 10:35:18 +02:00
Max Kellermann
4cb5e69811 output/Interface: add virtual method Interrupt()
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.
2020-10-02 10:20:39 +02:00
Max Kellermann
b0596291a8 output/Thread: simplify the main loop switch
Move the InternalPlay() call and the wake_cond.wait() call into the
`case Command::NONE` and revert all `continue` statements to a simple
`break`.
2020-10-02 10:10:53 +02:00
Max Kellermann
8f0a1a5d82 output/Interface: add noexcept 2020-10-01 20:44:14 +02:00
Max Kellermann
c0775d328c output/Filtered: move try/catch from IteratePause() to caller 2020-10-01 20:44:11 +02:00
Max Kellermann
4ca2c33181 doc/meson.build: check both html_manual and manpages
Closes https://github.com/MusicPlayerDaemon/MPD/issues/960
2020-09-30 12:11:20 +02:00
Max Kellermann
362f391b76 Merge remote-tracking branches 'neheb/defa', 'neheb/auto' and 'neheb/clocale' into master 2020-09-30 11:48:05 +02:00
Rosen Penev
980e32f69c remove clocale test
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>
2020-09-29 14:51:17 -07:00
Rosen Penev
dd639e18b8 clang-tidy: remove pointless std::move
Found with performance-move-const-arg

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-09-26 21:34:25 -07:00
Rosen Penev
c883f178b8 clang-tidy: use auto
Found with modernize-use-auto

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-09-26 21:33:35 -07:00
Max Kellermann
65d257675f increment version number to 0.22.1 2020-09-23 16:15:44 +02:00
1564 changed files with 22564 additions and 12044 deletions
.travis.ymlAUTHORSNEWSREADME.md
android
doc
meson.buildmeson_options.txt
python/build
src
BulkEdit.hxxChrono.hxxCommandLine.cxxCommandLine.hxxGitVersion.cxxGitVersion.hxxIcyMetaDataParser.cxxIcyMetaDataParser.hxxIdle.cxxIdle.hxxIdleFlags.cxxIdleFlags.hxxInstance.cxxInstance.hxxListen.cxxListen.hxxLocateUri.cxxLocateUri.hxxLog.cxxLog.hxxLogBackend.cxxLogBackend.hxxLogInit.cxxLogInit.hxxLogLevel.hxxMain.cxxMain.hxxMapper.cxxMapper.hxxMixRampInfo.hxxMusicBuffer.cxxMusicBuffer.hxxMusicChunk.cxxMusicChunk.hxxMusicChunkPtr.cxxMusicChunkPtr.hxxMusicPipe.cxxMusicPipe.hxxPartition.cxxPartition.hxxPermission.cxxPermission.hxxPlaylistDatabase.cxxPlaylistDatabase.hxxPlaylistError.cxxPlaylistError.hxxPlaylistFile.cxxPlaylistFile.hxxPlaylistPrint.cxxPlaylistPrint.hxxPlaylistSave.cxxPlaylistSave.hxxPluginUnavailable.hxxRemoteTagCache.cxxRemoteTagCache.hxxRemoteTagCacheHandler.hxxReplayGainConfig.hxxReplayGainGlobal.cxxReplayGainGlobal.hxxReplayGainInfo.cxxReplayGainInfo.hxxReplayGainMode.cxxReplayGainMode.hxxSingleMode.cxxSingleMode.hxxSongLoader.cxxSongLoader.hxxSongPrint.cxxSongPrint.hxxSongSave.cxxSongSave.hxxSongUpdate.cxxStateFile.cxxStateFile.hxxStateFileConfig.cxxStateFileConfig.hxxStats.cxxStats.hxxTagAny.cxxTagAny.hxxTagArchive.cxxTagArchive.hxxTagFile.cxxTagFile.hxxTagPrint.cxxTagPrint.hxxTagSave.cxxTagSave.hxxTagStream.cxxTagStream.hxxTimePrint.cxxTimePrint.hxx
android
archive
client
command
config
db
decoder
Bridge.cxxBridge.hxxClient.hxxCommand.hxxControl.cxxControl.hxxDecoderAPI.cxxDecoderAPI.hxxDecoderBuffer.cxxDecoderBuffer.hxxDecoderList.cxxDecoderList.hxxDecoderPlugin.cxxDecoderPlugin.hxxDecoderPrint.cxxDecoderPrint.hxxDomain.cxxDomain.hxxReader.cxxReader.hxxThread.cxxmeson.build
plugins
encoder
event
filter
fs
input
AsyncInputStream.cxxAsyncInputStream.hxxBufferedInputStream.cxxBufferedInputStream.hxxBufferingInputStream.cxxBufferingInputStream.hxxCondHandler.hxxError.cxxError.hxxFailingInputStream.hxxHandler.hxxIcyInputStream.cxxIcyInputStream.hxxInit.cxxInit.hxxInputPlugin.cxxInputPlugin.hxxInputStream.cxxInputStream.hxxLastInputStream.cxxLastInputStream.hxxLocalOpen.cxxLocalOpen.hxxMaybeBufferedInputStream.cxxMaybeBufferedInputStream.hxxOffset.hxxOpen.cxxProxyInputStream.cxxProxyInputStream.hxxPtr.hxxReader.cxxReader.hxxRegistry.cxxRegistry.hxxRemoteTagScanner.hxxRewindInputStream.cxxRewindInputStream.hxxScanTags.cxxScanTags.hxxTextInputStream.cxxTextInputStream.hxxThreadInputStream.cxxThreadInputStream.hxx
cache
meson.build
plugins
io
java
lib
alsa
cdio
chromaprint
crypto
curl
dbus
expat
ffmpeg
fmt
gcrypt
icu
jack
nfs
pcre
pipewire
pulse
smbclient
sqlite
systemd
upnp
xiph
yajl
zlib
ls.cxxls.hxx
mixer
neighbor
net
open.h
output
Client.hxxControl.cxxControl.hxxDefaults.cxxDefaults.hxxDomain.cxxDomain.hxxError.hxxFiltered.cxxFiltered.hxxFinish.cxxInit.cxxInterface.cxxInterface.hxxMultipleOutputs.cxxMultipleOutputs.hxxOutputAPI.hxxOutputCommand.cxxOutputCommand.hxxOutputPlugin.cxxOutputPlugin.hxxPrint.cxxPrint.hxxRegistry.cxxRegistry.hxxSharedPipeConsumer.cxxSharedPipeConsumer.hxxSource.cxxSource.hxxState.cxxState.hxxThread.cxxTimer.cxxTimer.hxxmeson.build
plugins
pcm
player
playlist
protocol
queue
song
sticker
storage
system
tag
thread
time
unix
util
win32
zeroconf
subprojects
test
win32

@@ -2,70 +2,40 @@ language: cpp
jobs:
include:
# Ubuntu Bionic (18.04) with GCC 7
# Ubuntu Focal (20.04) with GCC 9.3
- os: linux
dist: bionic
dist: focal
addons:
apt:
sources:
- sourceline: 'ppa:deadsnakes/ppa' # for Python 3.7 (required by Meson)
packages:
- meson
- libgtest-dev
- libboost-dev
- python3.6
- python3-urllib3
- ninja-build
before_install:
- wget https://bootstrap.pypa.io/get-pip.py
- /usr/bin/python3.6 get-pip.py --user --no-cache-dir
install:
- /usr/bin/python3.6 $HOME/.local/bin/pip install --user meson --no-cache-dir
env:
- MATRIX_EVAL="export PATH=\$HOME/.local/bin:\$PATH"
- libfmt-dev
# Ubuntu Bionic (18.04) with GCC 7 on big-endian
# Ubuntu Focal (20.04) with GCC 9.3 on big-endian
- os: linux
arch: s390x
dist: bionic
dist: focal
addons:
apt:
sources:
- sourceline: 'ppa:deadsnakes/ppa' # for Python 3.7 (required by Meson)
packages:
- meson
- libgtest-dev
- libboost-dev
- python3.6
- python3-urllib3
- ninja-build
before_install:
- wget https://bootstrap.pypa.io/get-pip.py
- /usr/bin/python3.6 get-pip.py --user --no-cache-dir
install:
- /usr/bin/python3.6 $HOME/.local/bin/pip install --user meson --no-cache-dir
env:
- MATRIX_EVAL="export PATH=\$HOME/.local/bin:\$PATH"
- libfmt-dev
# Ubuntu Bionic (18.04) with GCC 7 on ARM64
# Ubuntu Focal (20.04) with GCC 9.3 on ARM64
- os: linux
arch: arm64
dist: bionic
dist: focal
addons:
apt:
sources:
- sourceline: 'ppa:deadsnakes/ppa' # for Python 3.7 (required by Meson)
packages:
- meson
- libgtest-dev
- libboost-dev
- python3.6
- python3-urllib3
- ninja-build
before_install:
- wget https://bootstrap.pypa.io/get-pip.py
- /usr/bin/python3.6 get-pip.py --user --no-cache-dir
install:
- /usr/bin/python3.6 $HOME/.local/bin/pip install --user meson --no-cache-dir
env:
- MATRIX_EVAL="export PATH=\$HOME/.local/bin:\$PATH"
- libfmt-dev
# Ubuntu Trusty (16.04) with GCC 8
- os: linux
@@ -75,7 +45,7 @@ jobs:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa:mhier/libboost-latest'
- sourceline: 'ppa:mstipicevic/ninja-build-1-7-2'
- sourceline: 'ppa:ricotz/toolchain'
- sourceline: 'ppa:deadsnakes/ppa' # for Python 3.7 (required by Meson)
packages:
- g++-8
@@ -94,12 +64,14 @@ jobs:
- MATRIX_EVAL="export CC='ccache gcc-8' CXX='ccache g++-8' LDFLAGS=-fuse-ld=gold PATH=\$HOME/.local/bin:\$PATH"
- os: osx
osx_image: xcode10.3
osx_image: xcode11.6
addons:
homebrew:
packages:
- ccache
- meson
- fmt
- googletest
- icu4c
- ffmpeg
- libnfs
@@ -117,7 +89,6 @@ jobs:
- faad2
- wavpack
- libmpdclient
update: true
env:
- MATRIX_EVAL="export PATH=/usr/local/opt/ccache/libexec:$PATH HOMEBREW_NO_ANALYTICS=1"
@@ -134,13 +105,6 @@ before_install:
- eval "${MATRIX_EVAL}"
install:
# C++14
# Work around "Target /usr/local/lib/libgtest.a is a symlink
# belonging to nss. You can unlink it" during gtest install
- test "$TRAVIS_OS_NAME" != "osx" || brew unlink nss
- test "$TRAVIS_OS_NAME" != "osx" || brew install https://gist.githubusercontent.com/Kronuz/96ac10fbd8472eb1e7566d740c4034f8/raw/gtest.rb
before_script:
- ccache -s

@@ -1,5 +1,5 @@
Music Player Daemon - http://www.musicpd.org
Copyright 2003-2020 The Music Player Daemon Project
Copyright 2003-2021 The Music Player Daemon Project
The following people have contributed code to MPD:

193
NEWS

@@ -1,3 +1,196 @@
ver 0.23.2 (2021/10/22)
* protocol
- fix "albumart" timeout bug
* input
- nfs: fix playback bug
* output
- pipewire: send artist and title to PipeWire
- pipewire: DSD support
* neighbor
- mention failed plugin name in error message
* player
- fix cross-fade regression
* fix crash with libfmt versions older than 7
ver 0.23.1 (2021/10/19)
* protocol
- use decimal notation instead of scientific notation
- "load" supports relative positions
* output
- emit "mixer" idle event when replay gain changes volume
- pipewire: emit "mixer" idle events on external volume change
- pipewire: attempt to change the graph sample rate
- snapcast: fix time stamp bug which caused "Failed to get chunk"
* fix libfmt linker problems
* fix broken password authentication
ver 0.23 (2021/10/14)
* protocol
- new command "getvol"
- show the audio format in "playlistinfo"
- support "listfiles" with arbitrary storage plugins
- support relative positions in "addid"
- fix relative positions in "move" and "moveid"
- add "position" parameter to "findadd" and "searchadd"
- add position parameter to "load"
* database
- proxy: require MPD 0.20 or later
- proxy: require libmpdclient 2.11 or later
- proxy: split search into chunks to avoid exceeding the output buffer
- simple: add option to hide CUE target songs
- upnp: support libnpupnp instead of libupnp
* archive
- zzip, iso9660: ignore file names which are invalid UTF-8
* decoder
- openmpt: new plugin
- wavpack: fix WVC file support
* player
- do not cross-fade songs shorter than 20 seconds
* output
- oss: support DSD over PCM
- pipewire: new plugin
- snapcast: new plugin
* tags
- new tags "ComposerSort", "Ensemble", "Movement", "MovementNumber", and "Location"
* split permission "player" from "control"
* add option "host_permissions"
* new build-time dependency: libfmt
ver 0.22.11 (2021/08/24)
* protocol
- fix "albumart" crash
* filter
- ffmpeg: pass "channel_layout" instead of "channels" to buffersrc
- ffmpeg: fix "av_buffersink_get_frame() failed: Resource temporarily unavailable"
- ffmpeg: support double-precision samples (by converting to single precision)
* Android
- build with NDK r23
- playlist_directory defaults to "/sdcard/Android/data/org.musicpd/files/playlists"
ver 0.22.10 (2021/08/06)
* protocol
- support "albumart" for virtual tracks in CUE sheets
* database
- simple: fix crash bug
- simple: fix absolute paths in CUE "as_directory" entries
- simple: prune CUE entries from database for non-existent songs
* input
- curl: fix crash bug after stream with Icy metadata was closed by peer
- tidal: remove defunct unmaintained plugin
* tags
- fix crash caused by bug in TagBuilder and a few potential reference leaks
* output
- httpd: fix missing tag after seeking into a new song
- oss: fix channel order of multi-channel files
* mixer
- alsa: fix yet more rounding errors
ver 0.22.9 (2021/06/23)
* database
- simple: load all .mpdignore files of all parent directories
* tags
- fix "readcomments" and "readpicture" on remote files with ID3 tags
* decoder
- ffmpeg: support the tags "sort_album", "album-sort", "artist-sort"
- ffmpeg: fix build failure with FFmpeg 3.4
* Android
- fix auto-start on boot in Android 8 or later
* Windows
- fix build failure with SQLite
ver 0.22.8 (2021/05/22)
* fix crash bug in "albumart" command (0.22.7 regression)
ver 0.22.7 (2021/05/19)
* protocol
- don't use glibc extension to parse time stamps
- optimize the "albumart" command
* input
- curl: send user/password in the first request, save one roundtrip
* decoder
- ffmpeg: fix build problem with FFmpeg 3.4
- gme: support RSN files
* storage
- curl: don't use glibc extension
* database
- simple: fix database corruption bug
* output
- fix crash when pausing with multiple partitions
- jack: enable on Windows
- httpd: send header "Access-Control-Allow-Origin: *"
- wasapi: add algorithm for finding usable audio format
- wasapi: use default device only if none was configured
- wasapi: add DoP support
ver 0.22.6 (2021/02/16)
* fix missing tags on songs in queue
ver 0.22.5 (2021/02/15)
* protocol
- error for malformed ranges instead of ignoring silently
- better error message for open-ended range with "move"
* database
- simple: fix missing CUE sheet metadata in "addid" command
* tags
- id: translate TPE3 to Conductor, not Performer
* archive
- iso9660: another fix for unaligned reads
* output
- httpd: error handling on Windows improved
- pulse: fix deadlock with "always_on"
* Windows:
- enable https:// support (via Schannel)
* Android
- work around "Permission denied" on mpd.conf
ver 0.22.4 (2021/01/21)
* protocol
- add command "binarylimit" to allow larger chunk sizes
- fix "readpicture" on 32 bit machines
- show duration and tags of songs in virtual playlist (CUE) folders
* storage
- curl: fix several WebDAV protocol bugs
* decoder
- dsdiff: apply padding to odd-sized chunks
* filter
- ffmpeg: detect the output sample format
* output
- moveoutput: fix always_on and tag lost on move
* Android
- enable https:// support (via OpenSSL)
ver 0.22.3 (2020/11/06)
* playlist
- add option "as_directory", making CUE file expansion optional
* storage
- curl: fix crash bug
* filter
- fix garbage after "Audio format not supported by filter" message
- ffmpeg: support planar output
- ffmpeg: support sample formats other than 16 bit
ver 0.22.2 (2020/10/28)
* database
- simple: purge songs and virtual directories for unavailable plugins
on update
* input
- qobuz/tidal: fix protocol errors due to newlines in error messages
- smbclient: disable by default due to libsmbclient crash bug
* playlist
- soundcloud: fix protocol errors due to newlines in error messages
* state_file: save on shutdown
ver 0.22.1 (2020/10/17)
* decoder
- opus: apply the OpusHead output gain even if there is no EBU R128 tag
- opus: fix track/album ReplayGain fallback
* output
- alsa: don't deadlock when the ALSA driver is buggy
- jack, pulse: reduce the delay when stopping or pausing playback
* playlist
- cue: fix two crash bugs
* state_file: fix the state_file_interval setting
ver 0.22 (2020/09/23)
* protocol
- "findadd"/"searchadd"/"searchaddpl" support the "sort" and

@@ -14,7 +14,7 @@ For basic installation instructions
- [Manual](http://www.musicpd.org/doc/user/)
- [Forum](http://forum.musicpd.org/)
- [IRC](irc://chat.freenode.net/#mpd)
- [IRC](ircs://irc.libera.chat:6697/#mpd)
- [Bug tracker](https://github.com/MusicPlayerDaemon/MPD/issues/)
# Developers

@@ -2,10 +2,10 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.musicpd"
android:installLocation="auto"
android:versionCode="50"
android:versionName="0.22">
android:versionCode="62"
android:versionName="0.23.2">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28"/>
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="29"/>
<uses-feature android:name="android.software.leanback"
android:required="false" />
@@ -17,8 +17,11 @@
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<application android:allowBackup="true"
android:requestLegacyExternalStorage="true"
android:icon="@drawable/icon"
android:banner="@drawable/icon"
android:label="@string/app_name">
@@ -40,6 +43,7 @@
<receiver android:name=".Receiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.HEADSET_PLUG" />
</intent-filter>
</receiver>
<service android:name=".Main" android:process=":main"/>

@@ -24,15 +24,13 @@ android_abis = {
'armeabi-v7a': {
'arch': 'arm-linux-androideabi',
'ndk_arch': 'arm',
'toolchain_arch': 'arm-linux-androideabi',
'llvm_triple': 'armv7-linux-androideabi',
'cflags': '-fpic -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp',
'cflags': '-fpic -mfpu=neon -mfloat-abi=softfp',
},
'arm64-v8a': {
'arch': 'aarch64-linux-android',
'ndk_arch': 'arm64',
'toolchain_arch': 'aarch64-linux-android',
'llvm_triple': 'aarch64-linux-android',
'cflags': '-fpic',
},
@@ -40,7 +38,6 @@ android_abis = {
'x86': {
'arch': 'i686-linux-android',
'ndk_arch': 'x86',
'toolchain_arch': 'x86',
'llvm_triple': 'i686-linux-android',
'cflags': '-fPIC -march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32',
},
@@ -48,7 +45,6 @@ android_abis = {
'x86_64': {
'arch': 'x86_64-linux-android',
'ndk_arch': 'x86_64',
'toolchain_arch': 'x86_64',
'llvm_triple': 'x86_64-linux-android',
'cflags': '-fPIC -m64',
},
@@ -84,36 +80,29 @@ class AndroidNdkToolchain:
ndk_arch = abi_info['ndk_arch']
android_api_level = '21'
# select the NDK compiler
gcc_version = '4.9'
install_prefix = os.path.join(arch_path, 'root')
self.arch = arch
self.actual_arch = arch
self.install_prefix = install_prefix
toolchain_path = os.path.join(ndk_path, 'toolchains', abi_info['toolchain_arch'] + '-' + gcc_version, 'prebuilt', build_arch)
llvm_path = os.path.join(ndk_path, 'toolchains', 'llvm', 'prebuilt', build_arch)
llvm_triple = abi_info['llvm_triple'] + android_api_level
common_flags = '-Os -g'
common_flags += ' ' + abi_info['cflags']
toolchain_bin = os.path.join(toolchain_path, 'bin')
llvm_bin = os.path.join(llvm_path, 'bin')
self.cc = os.path.join(llvm_bin, 'clang')
self.cxx = os.path.join(llvm_bin, 'clang++')
common_flags += ' -target ' + llvm_triple + ' -integrated-as -gcc-toolchain ' + toolchain_path
common_flags += ' -target ' + llvm_triple
common_flags += ' -fvisibility=hidden -fdata-sections -ffunction-sections'
# required flags from https://android.googlesource.com/platform/ndk/+/ndk-release-r20/docs/BuildSystemMaintainers.md#additional-required-arguments
common_flags += ' -fno-addrsig'
self.ar = os.path.join(toolchain_bin, arch + '-ar')
self.ranlib = os.path.join(toolchain_bin, arch + '-ranlib')
self.nm = os.path.join(toolchain_bin, arch + '-nm')
self.strip = os.path.join(toolchain_bin, arch + '-strip')
self.ar = os.path.join(llvm_bin, 'llvm-ar')
self.ranlib = os.path.join(llvm_bin, 'llvm-ranlib')
self.nm = os.path.join(llvm_bin, 'llvm-nm')
self.strip = os.path.join(llvm_bin, 'llvm-strip')
self.cflags = common_flags
self.cxxflags = common_flags
@@ -151,10 +140,7 @@ class AndroidNdkToolchain:
# default one on the build host
import shutil
bin_dir = os.path.join(install_prefix, 'bin')
try:
os.makedirs(bin_dir)
except:
pass
os.makedirs(bin_dir, exist_ok=True)
self.pkg_config = shutil.copy(os.path.join(mpd_path, 'build', 'pkg-config.sh'),
os.path.join(bin_dir, 'pkg-config'))
self.env['PKG_CONFIG'] = self.pkg_config
@@ -164,7 +150,6 @@ from build.libs import *
thirdparty_libs = [
libmpdclient,
libogg,
libvorbis,
opus,
flac,
libid3tag,
@@ -172,8 +157,8 @@ thirdparty_libs = [
wildmidi,
gme,
ffmpeg,
openssl,
curl,
libexpat,
libnfs,
boost,
]

@@ -5,8 +5,8 @@ android_ndk = get_option('android_ndk')
android_sdk = get_option('android_sdk')
android_abi = get_option('android_abi')
android_sdk_build_tools_version = '27.0.0'
android_sdk_platform = 'android-23'
android_sdk_build_tools_version = '29.0.3'
android_sdk_platform = 'android-29'
android_build_tools_dir = join_paths(android_sdk, 'build-tools', android_sdk_build_tools_version)
android_sdk_platform_dir = join_paths(android_sdk, 'platforms', android_sdk_platform)

@@ -23,6 +23,12 @@
android:layout_height="wrap_content"
android:text="@string/checkbox_wakelock" />
<CheckBox
android:id="@+id/pause_on_headphones_disconnect"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/checkbox_pause_on_headphones_disconnect" />
<TextView
android:id="@+id/status"
android:layout_width="wrap_content"

@@ -8,4 +8,5 @@
<string name="toggle_button_run_off">MPD is not running</string>
<string name="checkbox_run_on_boot">Run MPD automatically on boot</string>
<string name="checkbox_wakelock">Prevent suspend when MPD is running (Wakelock)</string>
<string name="checkbox_pause_on_headphones_disconnect">Pause MPD when headphones disconnect</string>
</resources>

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -33,4 +33,5 @@ public class Bridge {
public static native void run(Context context, LogListener logListener);
public static native void shutdown();
public static native void pause();
}

@@ -5,6 +5,7 @@ interface IMain
{
void start();
void stop();
void setPauseOnHeadphonesDisconnect(boolean enabled);
void setWakelockEnabled(boolean enabled);
boolean isRunning();
void registerCallback(IMainCallback cb);

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -24,9 +24,13 @@ import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothClass;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Build;
import android.os.IBinder;
@@ -55,6 +59,7 @@ public class Main extends Service implements Runnable {
private String mError = null;
private final RemoteCallbackList<IMainCallback> mCallbacks = new RemoteCallbackList<IMainCallback>();
private final IBinder mBinder = new MainStub(this);
private boolean mPauseOnHeadphonesDisconnect = false;
private PowerManager.WakeLock mWakelock = null;
static class MainStub extends IMain.Stub {
@@ -68,6 +73,9 @@ public class Main extends Service implements Runnable {
public void stop() {
mService.stop();
}
public void setPauseOnHeadphonesDisconnect(boolean enabled) {
mService.setPauseOnHeadphonesDisconnect(enabled);
}
public void setWakelockEnabled(boolean enabled) {
mService.setWakelockEnabled(enabled);
}
@@ -191,6 +199,28 @@ public class Main extends Service implements Runnable {
if (mThread != null)
return;
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_HEADSET_PLUG);
filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED);
filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (!mPauseOnHeadphonesDisconnect) {
return;
}
if (intent.getAction().equals(Intent.ACTION_HEADSET_PLUG)) {
if (intent.hasExtra("state") && intent.getIntExtra("state", 0) == 0)
pause();
} else {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device.getBluetoothClass().hasService(BluetoothClass.Service.AUDIO))
pause();
}
}
}, filter);
final Intent mainIntent = new Intent(this, Settings.class);
mainIntent.setAction("android.intent.action.MAIN");
mainIntent.addCategory("android.intent.category.LAUNCHER");
@@ -241,6 +271,21 @@ public class Main extends Service implements Runnable {
stopSelf();
}
private void pause() {
if (mThread != null) {
if (mThread.isAlive()) {
synchronized (this) {
if (mStatus == MAIN_STATUS_STARTED)
Bridge.pause();
}
}
}
}
private void setPauseOnHeadphonesDisconnect(boolean enabled) {
mPauseOnHeadphonesDisconnect = enabled;
}
private void setWakelockEnabled(boolean enabled) {
if (enabled && mWakelock == null) {
PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
@@ -368,6 +413,19 @@ public class Main extends Service implements Runnable {
}
}
public boolean setPauseOnHeadphonesDisconnect(boolean enabled) {
synchronized (this) {
if (mIMain != null) {
try {
mIMain.setPauseOnHeadphonesDisconnect(enabled);
return true;
} catch (RemoteException e) {
}
}
return false;
}
}
public boolean setWakelockEnabled(boolean enabled) {
synchronized (this) {
if (mIMain != null) {
@@ -414,6 +472,15 @@ public class Main extends Service implements Runnable {
* start Main service without any callback
*/
public static void start(Context context, boolean wakelock) {
context.startService(new Intent(context, Main.class).putExtra("wakelock", wakelock));
Intent intent = new Intent(context, Main.class)
.putExtra("wakelock", wakelock);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
/* in Android 8+, we need to use this method
or else we'll get "IllegalStateException:
app is in background" */
context.startForegroundService(intent);
else
context.startService(intent);
}
}

@@ -1,6 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -59,6 +59,7 @@ public class Settings extends Activity {
public static class Preferences {
public static final String KEY_RUN_ON_BOOT ="run_on_boot";
public static final String KEY_WAKELOCK ="wakelock";
public static final String KEY_PAUSE_ON_HEADPHONES_DISCONNECT ="pause_on_headphones_disconnect";
public static SharedPreferences get(Context context) {
return context.getSharedPreferences(TAG, MODE_PRIVATE);
@@ -154,6 +155,9 @@ public class Settings extends Activity {
if (Preferences.getBoolean(Settings.this,
Preferences.KEY_WAKELOCK, false))
mClient.setWakelockEnabled(true);
if (Preferences.getBoolean(Settings.this,
Preferences.KEY_PAUSE_ON_HEADPHONES_DISCONNECT, false))
mClient.setPauseOnHeadphonesDisconnect(true);
} else {
mClient.stop();
}
@@ -179,6 +183,15 @@ public class Settings extends Activity {
}
};
private final OnCheckedChangeListener mOnPauseOnHeadphonesDisconnectChangeListener = new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
Preferences.putBoolean(Settings.this, Preferences.KEY_PAUSE_ON_HEADPHONES_DISCONNECT, isChecked);
if (mClient != null && mClient.isRunning())
mClient.setPauseOnHeadphonesDisconnect(isChecked);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
/* TODO: this sure is the wrong place to request
@@ -211,6 +224,11 @@ public class Settings extends Activity {
if (Preferences.getBoolean(this, Preferences.KEY_WAKELOCK, false))
checkbox.setChecked(true);
checkbox = (CheckBox) findViewById(R.id.pause_on_headphones_disconnect);
checkbox.setOnCheckedChangeListener(mOnPauseOnHeadphonesDisconnectChangeListener);
if (Preferences.getBoolean(this, Preferences.KEY_PAUSE_ON_HEADPHONES_DISCONNECT, false))
checkbox.setChecked(true);
super.onCreate(savedInstanceState);
}

66
doc/client.rst Normal file

@@ -0,0 +1,66 @@
Client Developer's Manual
#########################
Introduction
************
MPD is a music player without a user interface. The user interface
will be provided by independent clients, which connect to MPD over
socket connections (TCP or local sockets).
This chapter describes how to develop a client.
Before you develop a new client, consider joining an existing client
project. There are many clients, but few are mature; we need fewer,
but better clients.
Client Libraries
****************
There are many libraries which help with connecting to MPD. If you
develop a MPD client, use a library instead of reinventing the wheel.
The MPD website has a list of libraries: https://www.musicpd.org/libs/
Connecting to MPD
*****************
Do not hard-code your client to connect to ``localhost:6600``.
Instead, use the defaults of the client library. For example, with
:program:`libmpdclient`, don't do::
c = mpd_connection_new("localhost", 6600, 30000);
Instead, do::
c = mpd_connection_new(NULL, 0, 0);
This way, the library can choose the best defaults, maybe derived from
environment variables, so all MPD clients use the same settings.
If you need to reimplement those defaults (or if you are developing a
client library), this is a good set of addresses to attempt to connect
to:
- if the environment variable :envvar:`MPD_HOST` is set:
``$MPD_HOST:$MPD_PORT`` (:envvar:`MPD_PORT` defaulting to 6600)
- if the environment variable :envvar:`XDG_RUNTIME_DIR` is set:
``$XDG_RUNTIME_DIR/mpd/socket``
- :file:`/run/mpd/socket`
- ``localhost:$MPD_PORT`` (:envvar:`MPD_PORT` defaulting to 6600)
Environment Variables
*********************
The following environment variables should be obeyed by all clients
(preferably by the client library):
- :envvar:`MPD_HOST`: the host (or local socket path) to connect to;
on Linux, this may start with a ``@`` to connect to an abstract
socket. To use a password with MPD, set :envvar:`MPD_HOST` to
``password@host`` (then abstract socket requires double ``@``:
``password@@socket``).
- :envvar:`MPD_PORT`: the port number; defaults to 6600.
- :envvar:`MPD_TIMEOUT`: timeout for connecting to MPD and for waiting
for MPD's response in seconds. A good default is 30 seconds.

@@ -30,7 +30,7 @@ master_doc = 'index'
# General information about the project.
project = 'Music Player Daemon'
copyright = '2003-2020 The Music Player Daemon Project'
copyright = '2003-2021 The Music Player Daemon Project'
author = 'Max Kellermann'
# The version info for the project you're documenting, acts as replacement for
@@ -38,9 +38,9 @@ author = 'Max Kellermann'
# built documents.
#
# The short X.Y version.
version = '0.22'
version = '0.23.2'
# The full version, including alpha/beta/rc tags.
release = version
#release = version + '~git'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

@@ -68,11 +68,11 @@ 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.21.x``) where only bug
- the "stable" branch (currently called ``v0.22.x``) where only bug
fixes are merged.
Once :program:`MPD` 0.22 is released, a new branch called ``v0.22.x``
will be created for 0.22 bug-fix releases; after that, ``v0.21.x``
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

@@ -8,6 +8,7 @@ Music Player Daemon
user
plugins
developer
client
protocol

@@ -1,4 +1,4 @@
if not get_option('html_manual')
if not get_option('html_manual') and not get_option('manpages')
subdir_done()
endif
@@ -14,6 +14,7 @@ if get_option('html_manual')
input: [
'index.rst', 'user.rst', 'developer.rst',
'plugins.rst',
'client.rst',
'protocol.rst',
'conf.py',
],
@@ -22,20 +23,6 @@ if get_option('html_manual')
install: true,
install_dir: join_paths(get_option('datadir'), 'doc', meson.project_name()),
)
custom_target(
'upload',
input: sphinx_output,
output: 'upload',
build_always_stale: true,
command: [
'rsync', '-vpruz', '--delete', meson.current_build_dir() + '/',
'www.musicpd.org:/var/www/mpd/doc/',
'--chmod=Dug+rwx,Do+rx,Fug+rw,Fo+r',
'--include=html', '--include=html/**',
'--exclude=*',
],
)
endif
if get_option('manpages')

@@ -13,7 +13,7 @@ DESCRIPTION
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 ``/etc/mpd.conf`` or uses ``CONF_FILE``.
then ``~/.mpdconf`` then ``~/.mpd/mpd.conf`` then ``/etc/mpd.conf`` or uses ``CONF_FILE``.
Read more about MPD at http://www.musicpd.org/
@@ -53,8 +53,8 @@ OPTIONS
FILES
-----
:file:`~/.mpdconf`
User configuration file.
:file:`$XDG_CONFIG_HOME/mpd/mpd.conf`
User configuration file (usually :file:`~/.config/mpd/mpd.conf`).
:file:`/etc/mpd.conf`
Global configuration file.

@@ -11,24 +11,34 @@ not specified on the command line, MPD first searches for it at
:file:`$XDG_CONFIG_HOME/mpd/mpd.conf` then at :file:`~/.mpdconf` then
at :file:`~/.mpd/mpd.conf` and then in :file:`/etc/mpd.conf`.
Lines beginning with a :samp:`#` character are comments. All other
non-empty lines specify parameters and their values. These lines
contain the parameter name and parameter value (surrounded by double
quotes) separated by whitespace (either tabs or spaces). For
example::
Each line in the configuration file contains a setting name and its value, e.g.:
parameter "value"
:code:`connection_timeout "5"`
The exception to this rule is the audio_output parameter, which is of
the form::
For settings which specify a filesystem path, the tilde is expanded:
:code:`music_directory "~/Music"`
Some of the settings are grouped in blocks with curly braces, e.g. per-plugin settings:
.. code-block:: none
audio_output {
parameter1 "value"
parameter2 "value"
type "alsa"
name "My ALSA output"
device "iec958:CARD=Intel,DEV=0"
mixer_control "PCM"
}
The :code:`include` directive can be used to include settings from
another file; the given file name is relative to the current file:
Parameters that take a file or directory as an argument should use absolute paths.
:code:`include "other.conf"`
You can use include_optional instead if you want the included file to be
optional; the directive will be ignored if the file does not exist:
:code:`include_optional "may_not_exist.conf"`
See :file:`docs/mpdconf.example` in the source tarball for an example
configuration file.
@@ -38,7 +48,7 @@ Please read the MPD user manual for a complete configuration guide:
http://www.musicpd.org/doc/user/
REQUIRED PARAMETERS
OPTIONAL PARAMETERS
-------------------
db_file <file>
@@ -47,9 +57,6 @@ db_file <file>
log_file <file>
This specifies where the log file should be located. The special value "syslog" makes MPD use the local syslog daemon.
OPTIONAL PARAMETERS
-------------------
sticker_file <file>
The location of the sticker database. This is a database which manages
dynamic information attached to songs.
@@ -83,7 +90,7 @@ user <username>
port <port>
This specifies the port that mpd listens on. The default is 6600.
log_level <default, secure, or verbose>
log_level <level>
Suppress all messages below the given threshold. The following
log levels are available:
@@ -123,7 +130,8 @@ audio_output
replaygain <off or album or track or auto>
If specified, mpd will adjust the volume of songs played using ReplayGain
tags (see http://www.replaygain.org/). Setting this to "album" will
tags (see https://wiki.hydrogenaud.io/index.php?title=Replaygain).
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
@@ -190,8 +198,8 @@ mixer_type <hardware, software or none>
FILES
-----
:file:`~/.mpdconf`
User configuration file.
:file:`$XDG_CONFIG_HOME/mpd/mpd.conf`
User configuration file (usually :file:`~/.config/mpd/mpd.conf`).
:file:`/etc/mpd.conf`
Global configuration file.

@@ -5,7 +5,7 @@
# Files and directories #######################################################
#
# This setting controls the top directory which MPD will search to discover the
# available audio files and add them to the daemon's online database. This
# available audio files and add them to the daemon's online database. This
# setting defaults to the XDG directory, otherwise the music directory will be
# be disabled and audio files will only be accepted over ipc socket (using
# file:// protocol) or streaming files over an accepted protocol.
@@ -13,20 +13,20 @@
#music_directory "~/music"
#
# This setting sets the MPD internal playlist directory. The purpose of this
# directory is storage for playlists created by MPD. The server will use
# directory is storage for playlists created by MPD. The server will use
# playlist files not created by the server but only if they are in the MPD
# format. This setting defaults to playlist saving being disabled.
#
#playlist_directory "~/.mpd/playlists"
#
# This setting sets the location of the MPD database. This file is used to
# load the database at server start up and store the database while the
# load the database at server start up and store the database while the
# server is not up. This setting defaults to disabled which will allow
# MPD to accept files over ipc socket (using file:// protocol) or streaming
# files over an accepted protocol.
#
#db_file "~/.mpd/database"
#
#
# These settings are the locations for the daemon log files for the daemon.
# These logs are great for troubleshooting, depending on your log_level
# settings.
@@ -44,7 +44,7 @@
#
# This setting sets the location of the file which contains information about
# most variables to get MPD back into the same general shape it was in before
# it was brought down. This setting is disabled by default and the server
# it was brought down. This setting is disabled by default and the server
# state will be reset on server start up.
#
#state_file "~/.mpd/state"
@@ -74,7 +74,7 @@
#group "nogroup"
#
# This setting sets the address for the daemon to listen on. Careful attention
# should be paid if this is assigned to anything other then the default, any.
# should be paid if this is assigned to anything other than the default, any.
# This setting can deny access to control of the daemon. Not effective if
# systemd socket activiation is in use.
#
@@ -90,7 +90,8 @@
#port "6600"
#
# Suppress all messages below the given threshold. Use "verbose" for
# troubleshooting.
# troubleshooting. Available setting arguments are "notice", "info", "verbose",
# "warning" and "error".
#
#log_level "notice"
#
@@ -113,7 +114,7 @@
# the other supported tags:
#metadata_to_use "+comment"
#
# This setting enables automatic update of MPD's database when files in
# This setting enables automatic update of MPD's database when files in
# music_directory are changed.
#
#auto_update "yes"
@@ -128,7 +129,7 @@
# Symbolic link behavior ######################################################
#
# If this setting is set to "yes", MPD will discover audio files by following
# If this setting is set to "yes", MPD will discover audio files by following
# symbolic links outside of the configured music_directory.
#
#follow_outside_symlinks "yes"
@@ -163,7 +164,7 @@
#
#password "password@read,add,control,admin"
#
# This setting specifies the permissions a user has who has not yet logged in.
# This setting specifies the permissions a user has who has not yet logged in.
#
#default_permissions "read,add,control,admin"
#
@@ -172,7 +173,18 @@
# Database #######################################################################
#
# An example of a database section instead of the old 'db_file' setting.
# It enables mounting other storages into the music directory.
#
#database {
# plugin "simple"
# path "~/.local/share/mpd/db
# cache_directory "~/.local/share/mpd/cache"
#}
#
# An example of database config for a sattelite setup
#
#music_directory "nfs://fileserver.local/srv/mp3"
#database {
# plugin "proxy"
# host "other.mpd.host"
@@ -181,7 +193,6 @@
# Input #######################################################################
#
input {
plugin "curl"
# proxy "proxy.isp.com:8080"
@@ -194,8 +205,8 @@ input {
# Audio Output ################################################################
#
# MPD supports various audio output types, as well as playing through multiple
# audio outputs at the same time, through multiple audio_output settings
# MPD supports various audio output types, as well as playing through multiple
# audio outputs at the same time, through multiple audio_output settings
# blocks. Setting this block is optional, though the server will only attempt
# autodetection for one sound card.
#
@@ -361,7 +372,8 @@ input {
# the argument "off", "album", "track" or "auto". "auto" is a special mode that
# chooses between "track" and "album" depending on the current state of
# random playback. If random playback is enabled then "track" mode is used.
# See <http://www.replaygain.org> for more details about ReplayGain.
# See <https://wiki.hydrogenaud.io/index.php?title=Replaygain> for
# more details about ReplayGain.
# This setting is off by default.
#
#replaygain "album"
@@ -386,7 +398,7 @@ input {
#replaygain_limit "yes"
#
# This setting enables on-the-fly normalization volume adjustment. This will
# result in the volume of all playing audio to be adjusted so the output has
# result in the volume of all playing audio to be adjusted so the output has
# equal "loudness". This setting is disabled by default.
#
#volume_normalization "no"
@@ -395,7 +407,7 @@ input {
# Character Encoding ##########################################################
#
# If file or directory names do not display correctly for your locale then you
# If file or directory names do not display correctly for your locale then you
# may need to modify this setting.
#
#filesystem_charset "UTF-8"

@@ -23,11 +23,23 @@ The default plugin. Stores a copy of the database in memory. A file is used for
- The path of the cache directory for additional storages mounted at runtime. This setting is necessary for the **mount** protocol command.
* - **compress yes|no**
- Compress the database file using gzip? Enabled by default (if built with zlib).
* - **hide_playlist_targets yes|no**
- Hide songs which are referenced by playlists? Thas is,
playlist files which are represented in the database as virtual
directories (playlist plugin setting ``as_directory``). This
option is enabled by default and avoids duplicate songs; one
copy for the original file, and another copy in the virtual
directory of a CUE file referring to it.
proxy
-----
Provides access to the database of another :program:`MPD` instance using libmpdclient. This is useful when you mount the music directory via NFS/SMB, and the file server already runs a :program:`MPD` instance. Only the file server needs to update the database.
Provides access to the database of another :program:`MPD` instance
using `libmpdclient
<https://www.musicpd.org/libs/libmpdclient/>`_. This is useful when
you mount the music directory via NFS/SMB, and the file server already
runs a :program:`MPD` (0.20 or newer) instance. Only the file server
needs to update the database.
.. list-table::
:widths: 20 80
@@ -71,6 +83,11 @@ Load music files from a SMB/CIFS server. It is used when
:code:`music_directory` contains a ``smb://`` URI, for example
:samp:`smb://myfileserver/Music`.
Note that :file:`libsmbclient` has a serious bug which causes MPD to
crash, and therefore this plugin is disabled by default and should not
be used until the bug is fixed:
https://bugzilla.samba.org/show_bug.cgi?id=11413
nfs
---
@@ -205,6 +222,8 @@ will be in effect.
- Verify the peer's SSL certificate? `More information <http://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYPEER.html>`_.
* - **verify_host yes|no**
- Verify the certificate's name against host? `More information <http://curl.haxx.se/libcurl/c/CURLOPT_SSL_VERIFYHOST.html>`_.
* - **cacert**
- Set path to Certificate Authority (CA) bundle `More information <https://curl.se/libcurl/c/CURLOPT_CAINFO.html>`_.
ffmpeg
------
@@ -290,37 +309,6 @@ in the form ``qobuz://track/ID``, e.g.:
* - **format_id N**
- The `Qobuz format identifier <https://github.com/Qobuz/api-documentation/blob/master/endpoints/track/getFileUrl.md#parameters>`_, i.e. a number which chooses the format and quality to be requested from Qobuz. The default is "5" (320 kbit/s MP3).
tidal
-----
Play songs from the commercial streaming service `Tidal
<http://tidal.com/>`_. It plays URLs in the form ``tidal://track/ID``,
e.g.:
.. warning::
This plugin is currently defunct because Tidal has changed the
protocol and decided not to share documentation.
.. code-block:: none
mpc add tidal://track/59727857
.. list-table::
:widths: 20 80
:header-rows: 1
* - Setting
- Description
* - **token TOKEN**
- The Tidal application token. Since Tidal is unwilling to assign a token to MPD, this needs to be reverse-engineered from another (approved) Tidal client.
* - **username USERNAME**
- The Tidal user name.
* - **password PASSWORD**
- The Tidal password.
* - **audioquality Q**
- The Tidal "audioquality" parameter. Possible values: HI_RES, LOSSLESS, HIGH, LOW. Default is HIGH.
.. _decoder_plugins:
Decoder plugins
@@ -373,10 +361,14 @@ flac
Decodes FLAC files using libFLAC.
.. _decoder_dsdiff:
dsdiff
------
Decodes DFF files containing DSDIFF data (e.g. SACD rips).
Decodes DSDIFF (`Direct Stream Digital Interchange File Format
<http://www.sonicstudio.com/pdf/dsd/DSDIFF_1.5_Spec.pdf>`_) files
(:file:`*.dff`). These contain :ref:`DSD <dsd>` instead of PCM.
.. list-table::
:widths: 20 80
@@ -387,10 +379,14 @@ Decodes DFF files containing DSDIFF data (e.g. SACD rips).
* - **lsbitfirst yes|no**
- Decode the least significant bit first. Default is no.
.. _decoder_dsf:
dsf
---
Decodes DSF files containing DSDIFF data (e.g. SACD rips).
Decodes DSF
(<https://dsd-guide.com/sites/default/files/white-papers/DSFFileFormatSpec_E.pdf>)
files (:file:`*.dsf`). These contain :ref:`DSD <dsd>` instead of PCM.
fluidsynth
----------
@@ -469,9 +465,39 @@ Module player based on MODPlug.
* - Setting
- Description
* - **resampling_mode nearest|linear|spline|fir**
- Sets the resampling mode. "nearest" disables interpolation (good for chiptunes). "linear" makes modplug use linear interpolation (fast, good quality). "spline" makes modplug use cubic spline interpolation (high quality). "fir" makes modplug use 8-tap fir filter (extremely high quality). Defaults to "fir".
* - **loop_count**
- Number of times to loop the module if it uses backward loops. Default is 0 which prevents looping. -1 loops forever.
openmpt
-------
Module player based on `libopenmpt <https://lib.openmpt.org>`_.
.. list-table::
:widths: 20 80
:header-rows: 1
* - Setting
- Description
* - **repeat_count**
- Set how many times the module repeats. -1: repeat forever. 0: play once, repeat zero times (the default). n>0: play once and repeat n times after that.
* - **stereo_separation**
- Sets the stereo separation. The supported value range is [0,200]. Defaults to 100.
* - **interpolation_filter 0|1|2|4|8**
- Sets the interpolation filter. 0: internal default. 1: no interpolation (zero order hold). 2: linear interpolation. 4: cubic interpolation. 8: windowed sinc with 8 taps. Defaults to 0.
* - **override_mptm_interp_filter yes|no**
- If `interpolation_filter` has been changed, setting this to yes will force all MPTM modules to use that interpolation filter. If set to no, MPTM modules will play with their own interpolation filter regardless of the value of `interpolation_filter`. Defaults to no.
* - **volume_ramping**
- Sets the amount of volume ramping done by the libopenmpt mixer. The default value is -1, which indicates a recommended default value. The meaningful value range is [-1..10]. A value of 0 completely disables volume ramping. This might cause clicks in sound output. Higher values imply slower/softer volume ramps.
* - **sync_samples yes|no**
- Syncs sample playback when seeking. Defaults to yes.
* - **emulate_amiga yes|no**
- Enables the Amiga resampler for Amiga modules. This emulates the sound characteristics of the Paula chip and overrides the selected interpolation filter. Non-Amiga module formats are not affected by this setting. Defaults to yes.
* - **emulate_amiga_type**
- Configures the filter type to use for the Amiga resampler. Supported values are: "auto": Filter type is chosen by the library and might change. This is the default. "a500": Amiga A500 filter. "a1200": Amiga A1200 filter. "unfiltered": BLEP synthesis without model-specific filters. The LED filter is ignored by this setting. This filter mode is considered to be experimental and might change in the future. Defaults to "auto". Requires libopenmpt 0.5 or higher.
mpcdec
------
@@ -566,6 +592,10 @@ Encodes into `FLAC <https://xiph.org/flac/>`_ (lossless).
- Description
* - **compression**
- Sets the libFLAC compression level. The levels range from 0 (fastest, least compression) to 8 (slowest, most compression).
* - **oggflac yes|no**
- Configures if the stream should be Ogg FLAC versus native FLAC. Defaults to "no" (use native FLAC).
* - **oggchaining yes|no**
- Configures if the stream should use Ogg Chaining for in-stream metadata. Defaults to "no". Setting this to "yes" also enables Ogg FLAC.
lame
----
@@ -630,11 +660,15 @@ Encodes into `Ogg Opus <http://www.opus-codec.org/>`_.
* - Setting
- Description
* - **bitrate**
- Sets the data rate in bit per second. The special value "auto" lets libopus choose a rate (which is the default), and "max" uses the maximum possible data rate.
- Sets the data rate in bits per second. The special value "auto" lets libopus choose a rate (which is the default), and "max" uses the maximum possible data rate.
* - **complexity**
- Sets the `Opus complexity <https://wiki.xiph.org/OpusFAQ#What_is_the_complexity_of_Opus.3F>`_.
* - **signal**
- Sets the Opus signal type. Valid values are "auto" (the default), "voice" and "music".
* - **vbr yes|no|constrained**
- Sets the vbr mode. Setting to "yes" (default) enables variable bitrate, "no" forces constant bitrate and frame sizes, "constrained" uses constant bitrate analogous to CBR in AAC and MP3.
* - **packet_loss**
- Sets the expected packet loss percentage. This value can be increased from the default "0" for a more redundant stream at the expense of quality.
* - **opustags yes|no**
- Configures how metadata is interleaved into the stream. If set to yes, then metadata is inserted using ogg stream chaining, as specified in :rfc:`7845`. If set to no (the default), then ogg stream chaining is avoided and other output-dependent method is used, if available.
@@ -702,7 +736,7 @@ A resampler using `libsamplerate <http://www.mega-nerd.com/SRC/>`_ a.k.a. Secret
* - Name
- Description
* - **type**
- The interpolator type. See below for a list of known types.
- The interpolator type. Defaults to :samp:`2`. See below for a list of known types.
The following converter types are provided by libsamplerate:
@@ -750,6 +784,10 @@ Valid quality values for libsoxr:
If the quality is set to custom also the following settings are available:
.. list-table::
:widths: 20 80
:header-rows: 1
* - Name
- Description
* - **precision**
@@ -893,6 +931,10 @@ jack
The jack plugin connects to a `JACK server <http://jackaudio.org/>`_.
On Windows, this plugin loads :file:`libjack64.dll` at runtime. This
means you need to `download and install the JACK windows build
<https://jackaudio.org/downloads/>`_.
.. list-table::
:widths: 20 80
:header-rows: 1
@@ -969,6 +1011,8 @@ On Linux, OSS has been superseded by ALSA. Use the ALSA output plugin :ref:`alsa
- Description
* - **device PATH**
- Sets the path of the PCM device. If not specified, then MPD will attempt to open /dev/sound/dsp and /dev/dsp.
* - **dop yes|no**
- If set to yes, then DSD over PCM according to the `DoP standard <http://dsd-guide.com/dop-open-standard>`_ is enabled. This wraps DSD samples in fake 24 bit PCM, and is understood by some DSD capable products, but may be harmful to other hardware. Therefore, the default is no and you can enable the option at your own risk.
The according hardware mixer plugin understands the following settings:
@@ -1031,6 +1075,28 @@ The pipe plugin starts a program and writes raw PCM data into its standard input
* - **command CMD**
- This command is invoked with the shell.
pipewire
--------
Connect to a `PipeWire <https://pipewire.org/>`_ server. Requires
``libpipewire``.
.. list-table::
:widths: 20 80
:header-rows: 1
* - Setting
- Description
* - **target NAME**
- Link to the given target. If not specified, let the PipeWire
manager select a target. To get a list of available targets,
type ``pw-cli dump short Node``
* - **remote NAME**
- The name of the remote to connect to. The default is
``pipewire-0``.
* - **dsd yes|no**
- Enable DSD playback. This requires PipeWire 0.38.
.. _pulse_plugin:
pulse
@@ -1086,8 +1152,6 @@ You must set a format.
- Sets the host name of the `ShoutCast <http://www.shoutcast.com/>`_ / `IceCast <http://icecast.org/>`_ server.
* - **port PORTNUMBER**
- Connect to this port number on the specified host.
* - **timeout SECONDS**
- Set the timeout for the shout connection in seconds. Defaults to 2 seconds.
* - **protocol icecast2|icecast1|shoutcast**
- Specifies the protocol that wil be used to connect to the server. The default is "icecast2".
* - **tls disabled|auto|auto_no_plain|rfc2818|rfc2817**
@@ -1123,6 +1187,34 @@ audio API. Its primary use is local playback on Android, where
floating point samples.
snapcast
--------
Snapcast is a multiroom client-server audio player. This plugin
allows MPD to act as a `Snapcast
<https://github.com/badaix/snapcast>`__ server. Snapcast clients
connect to it and receive audio data from MPD.
You must set a format.
.. list-table::
:widths: 20 80
:header-rows: 1
* - Setting
- Description
* - **port P**
- Binds the Snapcast server to the specified port. The default
port is :samp:`1704`.
* - **bind_to_address ADDR**
- Binds the Snapcast server to the specified address. Multiple
addresses in parallel are not supported. The default is to
bind on all addresses on port :samp:`1704`.
* - **zeroconf yes|no**
- Publish the Snapcast server as service type ``_snapcast._tcp``
via Zeroconf (Avahi or Bonjour). Default is :samp:`yes`.
solaris
-------
The "Solaris" plugin runs only on SUN Solaris, and plays via /dev/audio.
@@ -1154,6 +1246,8 @@ The `Windows Audio Session API <https://docs.microsoft.com/en-us/windows/win32/c
- Enumerate all devices in log while playing started. Useful for device configuration. The default value is "no".
* - **exclusive yes|no**
- Exclusive mode blocks all other audio source, and get best audio quality without resampling. Stopping playing release the exclusive control of the output device. The default value is "no".
* - **dop yes|no**
- Enable DSD over PCM. Require exclusive mode. The default value is "no".
.. _filter_plugins:
@@ -1177,7 +1271,7 @@ This plugin requires building with ``libavfilter`` (FFmpeg).
* - **graph "..."**
- Specifies the ``libavfilter`` graph; read the `FFmpeg
documentation
<https://libav.org/documentation/libavfilter.html#Filtergraph-syntax-1>`_
<https://ffmpeg.org/ffmpeg-filters.html#Filtergraph-syntax-1>`_
for details
@@ -1224,23 +1318,25 @@ Playlist plugins
asx
---
Reads .asx playlist files.
Reads :file:`.asx` playlist files.
.. _cue_playlist:
cue
---
Reads .cue files.
Reads :file:`.cue` files.
embcue
------
Reads CUE sheets from the "CUESHEET" tag of song files.
Reads CUE sheets from the ``CUESHEET`` tag of song files.
m3u
---
Reads .m3u playlist files.
Reads :file:`.m3u` playlist files.
extm3u
------
Reads extended .m3u playlist files.
Reads extended :file:`.m3u` playlist files.
flac
----
@@ -1248,11 +1344,11 @@ Reads the cuesheet metablock from a FLAC file.
pls
---
Reads .pls playlist files.
Reads :file:`.pls` playlist files.
rss
---
Reads music links from .rss files.
Reads music links from :file:`.rss` files.
soundcloud
----------

@@ -69,11 +69,14 @@ that, the specified number of bytes of binary data follows, then a
newline, and finally the ``OK`` line.
If the object to be transmitted is large, the server may choose a
reasonable chunk size and transmit only a portion. Usually, the
response also contains a ``size`` line which specifies the total
(uncropped) size, and the command usually has a way to specify an
offset into the object; this way, the client can copy the whole file
without blocking the connection for too long.
reasonable chunk size and transmit only a portion. The maximum chunk
size can be changed by clients with the :ref:`binarylimit
<command_binarylimit>` command.
Usually, the response also contains a ``size`` line which specifies
the total (uncropped) size, and the command usually has a way to
specify an offset into the object; this way, the client can copy the
whole file without blocking the connection for too long.
Example::
@@ -281,11 +284,17 @@ The following tags are supported by :program:`MPD`:
* **name**: a name for this song. This is not the song title. The exact meaning of this tag is not well-defined. It is often used by badly configured internet radio stations with broken tags to squeeze both the artist name and the song title in one tag.
* **genre**: the music genre.
* **date**: the song's release date. This is usually a 4-digit year.
* **originaldate**: the song's original release date.
* **composer**: the artist who composed the song.
* **composersort**: same as composer, but for sorting.
* **performer**: the artist who performed the song.
* **conductor**: the conductor who conducted the song.
* **work**: `"a work is a distinct intellectual or artistic creation,
which can be expressed in the form of one or more audio recordings" <https://musicbrainz.org/doc/Work>`_
* **ensemble**: the ensemble performing this song, e.g. "Wiener Philharmoniker".
* **movement**: name of the movement, e.g. "Andante con moto".
* **movementnumber**: movement number, e.g. "2" or "II".
* **location**: location of the recording, e.g. "Royal Albert Hall".
* **grouping**: "used if the sound belongs to a larger category of
sounds/music" (`from the IDv2.4.0 TIT1 description
<http://id3.org/id3v2.4.0-frames>`_).
@@ -383,10 +392,14 @@ Command reference
Querying :program:`MPD`'s status
================================
.. _command_clearerror:
:command:`clearerror`
Clears the current error message in status (this is also
accomplished by any command that starts playback).
.. _command_currentsong:
:command:`currentsong`
Displays the song info of the current song (same song that
is identified in status). Information about the current song
@@ -407,7 +420,9 @@ Querying :program:`MPD`'s status
- ``update``: a database update has started or finished. If the database was modified during the update, the ``database`` event is also emitted.
- ``stored_playlist``: a stored playlist has been modified, renamed, created or deleted
- ``playlist``: the queue (i.e. the current playlist) has been modified
- ``player``: the player has been started, stopped or seeked
- ``player``: the player has been started, stopped or seeked or
tags of the currently playing song have changed (e.g. received
from stream)
- ``mixer``: the volume has been changed
- ``output``: an audio output has been added, removed or modified (e.g. renamed, enabled or disabled)
- ``options``: options like repeat, random, crossfade, replay gain
@@ -477,6 +492,8 @@ Querying :program:`MPD`'s status
:program:`MPD` versions used to have a "magic" value for
"unknown", e.g. ":samp:`volume: -1`".
.. _command_stats:
:command:`stats`
Displays statistics.
@@ -492,17 +509,25 @@ Querying :program:`MPD`'s status
Playback options
================
.. _command_consume:
:command:`consume {STATE}` [#since_0_15]_
Sets consume state to ``STATE``,
``STATE`` should be 0 or 1.
When consume is activated, each song played is removed from playlist.
.. _command_crossfade:
:command:`crossfade {SECONDS}`
Sets crossfading between songs.
.. _command_mixrampdb:
:command:`mixrampdb {deciBels}`
Sets the threshold at which songs will be overlapped. Like crossfading but doesn't fade the track volume, just overlaps. The songs need to have MixRamp tags added by an external tool. 0dB is the normalized maximum volume so use negative values, I prefer -17dB. In the absence of mixramp tags crossfading will be used. See http://sourceforge.net/projects/mixramp
.. _command_mixrampdelay:
:command:`mixrampdelay {SECONDS}`
Additional time subtracted from the overlap calculated by mixrampdb. A value of "nan" disables MixRamp overlapping and falls back to crossfading.
@@ -512,6 +537,8 @@ Playback options
Sets random state to ``STATE``,
``STATE`` should be 0 or 1.
.. _command_repeat:
:command:`repeat {STATE}`
Sets repeat state to ``STATE``,
``STATE`` should be 0 or 1.
@@ -522,12 +549,28 @@ Playback options
Sets volume to ``VOL``, the range of
volume is 0-100.
.. _command_getvol:
:command:`getvol`
Read the volume. The result is a ``volume:`` line like in
:ref:`status <command_status>`. If there is no mixer, MPD will
emit an empty response. Example::
getvol
volume: 42
OK
.. _command_single:
:command:`single {STATE}` [#since_0_15]_
Sets single state to ``STATE``,
``STATE`` should be ``0``, ``1`` or ``oneshot`` [#since_0_20]_.
``STATE`` should be ``0``, ``1`` or ``oneshot`` [#since_0_21]_.
When single is activated, playback is stopped after current song, or
song is repeated if the 'repeat' mode is enabled.
.. _command_replay_gain_mode:
:command:`replay_gain_mode {MODE}` [#since_0_16]_
Sets the replay gain mode. One of
``off``,
@@ -541,11 +584,15 @@ Playback options
This command triggers the
``options`` idle event.
.. _command_replay_gain_status:
:command:`replay_gain_status`
Prints replay gain options. Currently, only the
variable ``replay_gain_mode`` is
returned.
.. _command_volume:
:command:`volume {CHANGE}`
Changes volume by amount ``CHANGE``.
Deprecated, use :ref:`setvol <command_setvol>` instead.
@@ -553,41 +600,59 @@ Playback options
Controlling playback
====================
.. _command_next:
:command:`next`
Plays next song in the playlist.
.. _command_pause:
:command:`pause {STATE}`
Pause or resume playback. Pass :samp:`1` to pause playback or
:samp:`0` to resume playback. Without the parameter, the pause
state is toggled.
.. _command_play:
:command:`play [SONGPOS]`
Begins playing the playlist at song number
``SONGPOS``.
.. _command_playid:
:command:`playid [SONGID]`
Begins playing the playlist at song
``SONGID``.
.. _command_previous:
:command:`previous`
Plays previous song in the playlist.
.. _command_seek:
:command:`seek {SONGPOS} {TIME}`
Seeks to the position ``TIME`` (in
seconds; fractions allowed) of entry
``SONGPOS`` in the playlist.
.. _command_seekid:
:command:`seekid {SONGID} {TIME}`
Seeks to the position ``TIME`` (in
seconds; fractions allowed) of song
``SONGID``.
.. _command_seekcur:
:command:`seekcur {TIME}`
Seeks to the position ``TIME`` (in
seconds; fractions allowed) within the current song. If
prefixed by ``+`` or ``-``, then the time is relative to the
current playing position.
.. _command_stop:
:command:`stop`
Stops playing.
@@ -622,11 +687,20 @@ client can always be sure the correct song is being used.
Many commands come in two flavors, one for each address type.
Whenever possible, ids should be used.
.. _command_add:
:command:`add {URI}`
Adds the file ``URI`` to the playlist
(directories add recursively). ``URI``
can also be a single file.
Clients that are connected via local socket may add arbitrary
local files (URI is an absolute path). Example::
add "/home/foo/Music/bar.ogg"
.. _command_addid:
:command:`addid {URI} [POSITION]`
Adds a song to the playlist (non-recursive) and returns the
song id. ``URI`` is always a single file or URL. For example::
@@ -635,6 +709,15 @@ Whenever possible, ids should be used.
Id: 999
OK
If the second parameter is given, then the song is inserted at the
specified position. If the parameter starts with ``+`` or ``-``,
then it is relative to the current song; e.g. ``+0`` inserts right
after the current song and ``-0`` inserts right before the current
song (i.e. zero songs between the current song and the newly added
song).
.. _command_clear:
:command:`clear`
Clears the queue.
@@ -643,21 +726,37 @@ Whenever possible, ids should be used.
:command:`delete [{POS} | {START:END}]`
Deletes a song from the playlist.
.. _command_deleteid:
:command:`deleteid {SONGID}`
Deletes the song ``SONGID`` from the
playlist
.. _command_move:
:command:`move [{FROM} | {START:END}] {TO}`
Moves the song at ``FROM`` or range of songs
at ``START:END`` [#since_0_15]_ to ``TO``
in the playlist.
If ``TO`` starts with ``+`` or ``-``, then it is relative to the
current song; e.g. ``+0`` moves to right after the current song
and ``-0`` moves to right before the current song (i.e. zero songs
between the current song and the moved range).
.. _command_moveid:
:command:`moveid {FROM} {TO}`
Moves the song with ``FROM`` (songid) to
``TO`` (playlist index) in the
playlist. If ``TO`` is negative, it
is relative to the current song in the playlist (if
there is one).
playlist.
If ``TO`` starts with ``+`` or ``-``, then it is relative to the
current song; e.g. ``+0`` moves to right after the current song
and ``-0`` moves to right before the current song (i.e. zero songs
between the current song and the moved song).
.. _command_playlist:
:command:`playlist`
@@ -666,10 +765,14 @@ Whenever possible, ids should be used.
Do not use this, instead use :ref:`playlistinfo
<command_playlistinfo>`.
:command:`playlistfind {TAG} {NEEDLE}`
.. _command_playlistfind:
:command:`playlistfind {FILTER}`
Finds songs in the queue with strict
matching.
.. _command_playlistid:
:command:`playlistid {SONGID}`
Displays a list of songs in the playlist.
``SONGID`` is optional and specifies a
@@ -683,10 +786,14 @@ Whenever possible, ids should be used.
``SONGPOS`` or the range of songs
``START:END`` [#since_0_15]_
:command:`playlistsearch {TAG} {NEEDLE}`
.. _command_playlistsearch:
:command:`playlistsearch {FILTER}`
Searches case-insensitively for partial matches in the
queue.
.. _command_plchanges:
:command:`plchanges {VERSION} [START:END]`
Displays changed songs currently in the playlist since
``VERSION``. Start and end positions may
@@ -696,6 +803,8 @@ Whenever possible, ids should be used.
To detect songs that were deleted at the end of the
playlist, use playlistlength returned by status command.
.. _command_plchangesposid:
:command:`plchangesposid {VERSION} [START:END]`
Displays changed songs currently in the playlist since
``VERSION``. This function only
@@ -721,6 +830,8 @@ Whenever possible, ids should be used.
Same as :ref:`priod <command_prio>`,
but address the songs with their id.
.. _command_rangeid:
:command:`rangeid {ID} {START:END}` [#since_0_19]_
Since :program:`MPD`
0.19 Specifies the portion of the
@@ -731,19 +842,27 @@ Whenever possible, ids should be used.
range, play everything". A song that is currently
playing cannot be manipulated this way.
.. _command_shuffle:
:command:`shuffle [START:END]`
Shuffles the queue.
``START:END`` is optional and specifies
a range of songs.
.. _command_swap:
:command:`swap {SONG1} {SONG2}`
Swaps the positions of ``SONG1`` and
``SONG2``.
.. _command_swapid:
:command:`swapid {SONG1} {SONG2}`
Swaps the positions of ``SONG1`` and
``SONG2`` (both song ids).
.. _command_addtagid:
:command:`addtagid {SONGID} {TAG} {VALUE}`
Adds a tag to the specified song. Editing song tags is
only possible for remote songs. This change is
@@ -751,6 +870,8 @@ Whenever possible, ids should be used.
the server, and the data is gone when the song gets
removed from the queue.
.. _command_cleartagid:
:command:`cleartagid {SONGID} [TAG]`
Removes tags from the specified song. If
``TAG`` is not specified, then all tag
@@ -772,14 +893,20 @@ playlists in arbitrary location (absolute path including the suffix;
allowed only for clients that are connected via local socket), or
remote playlists (absolute URI with a supported scheme).
.. _command_listplaylist:
:command:`listplaylist {NAME}`
Lists the songs in the playlist. Playlist plugins are
supported.
.. _command_listplaylistinfo:
:command:`listplaylistinfo {NAME}`
Lists the songs with metadata in the playlist. Playlist
plugins are supported.
.. _command_listplaylists:
:command:`listplaylists`
Prints a list of the playlist directory.
After each playlist name the server sends its last
@@ -790,32 +917,50 @@ remote playlists (absolute URI with a supported scheme).
.. _command_load:
:command:`load {NAME} [START:END]`
:command:`load {NAME} [START:END] [POSITION]`
Loads the playlist into the current queue. Playlist
plugins are supported. A range may be specified to load
only a part of the playlist.
The ``POSITION`` parameter specifies where the songs will be
inserted into the queue; it can be relative as described in
:ref:`addid <command_addid>`. (This requires specifying the range
as well; the special value `0:` can be used if the whole playlist
shall be loaded at a certain queue position.)
.. _command_playlistadd:
:command:`playlistadd {NAME} {URI}`
Adds ``URI`` to the playlist
`NAME.m3u`.
`NAME.m3u` will be created if it does
not exist.
.. _command_playlistclear:
:command:`playlistclear {NAME}`
Clears the playlist `NAME.m3u`.
.. _command_playlistdelete:
:command:`playlistdelete {NAME} {SONGPOS}`
Deletes ``SONGPOS`` from the
playlist `NAME.m3u`.
.. _command_playlistmove:
:command:`playlistmove {NAME} {FROM} {TO}`
Moves the song at position ``FROM`` in
the playlist `NAME.m3u` to the
position ``TO``.
.. _command_rename:
:command:`rename {NAME} {NEW_NAME}`
Renames the playlist `NAME.m3u` to `NEW_NAME.m3u`.
.. _command_rm:
:command:`rm {NAME}`
Removes the playlist `NAME.m3u` from
the playlist directory.
@@ -829,6 +974,8 @@ remote playlists (absolute URI with a supported scheme).
The music database
==================
.. _command_albumart:
:command:`albumart {URI} {OFFSET}`
Locate album art for the given song and return a chunk of an album
art image file at offset ``OFFSET``.
@@ -850,6 +997,8 @@ The music database
<8192 bytes>
OK
.. _command_count:
:command:`count {FILTER} [group {GROUPTYPE}]`
Count the number of songs and their total playtime in
the database matching ``FILTER`` (see
@@ -872,6 +1021,8 @@ The music database
don't have this group tag. It exists only if at least one such song is
found.
.. _command_getfingerprint:
:command:`getfingerprint {URI}`
Calculate the song's audio fingerprint. Example (abbreviated fingerprint)::
@@ -909,11 +1060,11 @@ The music database
.. _command_findadd:
:command:`findadd {FILTER} [sort {TYPE}] [window {START:END}]`
:command:`findadd {FILTER} [sort {TYPE}] [window {START:END}] [position POS]`
Search the database for songs matching
``FILTER`` (see :ref:`Filters <filter_syntax>`) and add them to
the queue. Parameters have the same meaning as for
:ref:`find <command_find>`.
:ref:`find <command_find>` and :ref:`searchadd <command_searchadd>`.
.. _command_list:
@@ -962,6 +1113,8 @@ The music database
:program:`MPD` whenever you need
something.
.. _command_listfiles:
:command:`listfiles {URI}`
Lists the contents of the directory
``URI``, including files are not
@@ -998,6 +1151,8 @@ The music database
use this command to read the tags of an arbitrary local
file (URI is an absolute path).
.. _command_readcomments:
:command:`readcomments {URI}`
Read "comments" (i.e. key-value pairs) from the file
specified by "URI". This "URI" can be a path relative
@@ -1014,6 +1169,8 @@ The music database
decoder plugins support it. For example, on Ogg files,
this lists the Vorbis comments.
.. _command_readpicture:
:command:`readpicture {URI} {OFFSET}`
Locate a picture for the given song and return a chunk of the
image file at offset ``OFFSET``. This is usually implemented by
@@ -1040,7 +1197,7 @@ The music database
.. _command_search:
:command:`search {FILTER} [sort {TYPE}] [window {START:END}]`
:command:`search {FILTER} [sort {TYPE}] [window {START:END}]
Search the database for songs matching
``FILTER`` (see :ref:`Filters <filter_syntax>`). Parameters
have the same meaning as for :ref:`find <command_find>`,
@@ -1048,13 +1205,18 @@ The music database
.. _command_searchadd:
:command:`searchadd {FILTER} [sort {TYPE}] [window {START:END}]`
:command:`searchadd {FILTER} [sort {TYPE}] [window {START:END}] [position POS]`
Search the database for songs matching
``FILTER`` (see :ref:`Filters <filter_syntax>`) and add them to
the queue.
Parameters have the same meaning as for :ref:`search <command_search>`.
The ``position`` parameter specifies where the songs will be
inserted.
.. _command_searchaddpl:
:command:`searchaddpl {NAME} {FILTER} [sort {TYPE}] [window {START:END}]`
Search the database for songs matching
``FILTER`` (see :ref:`Filters <filter_syntax>`) and add them to
@@ -1080,6 +1242,8 @@ The music database
job id in the :ref:`status <command_status>`
response.
.. _command_rescan:
:command:`rescan [URI]`
Same as :ref:`update <command_update>`,
but also rescans unmodified files.
@@ -1106,11 +1270,15 @@ only inside the :program:`MPD` process.
mount foo nfs://192.168.1.4/export/mp3
.. _command_unmount:
:command:`unmount {PATH}`
Unmounts the specified path. Example::
unmount foo
.. _command_listmounts:
:command:`listmounts`
Queries a list of all mounts. By default, this contains
just the configured ``music_directory``.
@@ -1123,6 +1291,8 @@ only inside the :program:`MPD` process.
storage: nfs://192.168.1.4/export/mp3
OK
.. _command_listneighbors:
:command:`listneighbors`
Queries a list of "neighbors" (e.g. accessible file
servers on the local net). Items on that list may be
@@ -1158,28 +1328,40 @@ Objects which may have stickers are addressed by their object
type ("song" for song objects) and their URI (the path within
the database for songs).
.. _command_sticker_get:
:command:`sticker get {TYPE} {URI} {NAME}`
Reads a sticker value for the specified object.
.. _command_sticker_set:
:command:`sticker set {TYPE} {URI} {NAME} {VALUE}`
Adds a sticker value to the specified object. If a
sticker item with that name already exists, it is
replaced.
.. _command_sticker_delete:
:command:`sticker delete {TYPE} {URI} [NAME]`
Deletes a sticker value from the specified object. If
you do not specify a sticker name, all sticker values
are deleted.
.. _command_sticker_list:
:command:`sticker list {TYPE} {URI}`
Lists the stickers for the specified object.
.. _command_sticker_find:
:command:`sticker find {TYPE} {URI} {NAME}`
Searches the sticker database for stickers with the
specified name, below the specified directory (URI).
For each matching song, it prints the URI and that one
sticker's value.
.. _command_sticker_find_value:
:command:`sticker find {TYPE} {URI} {NAME} = {VALUE}`
Searches for stickers with the given value.
@@ -1189,6 +1371,8 @@ the database for songs).
Connection settings
===================
.. _command_close:
:command:`close`
Closes the connection to :program:`MPD`.
:program:`MPD` will try to send the
@@ -1199,6 +1383,8 @@ Connection settings
Clients should not use this command; instead, they should just
close the socket.
.. _command_kill:
:command:`kill`
Kills :program:`MPD`.
@@ -1206,14 +1392,31 @@ Connection settings
instead, or better: let your service manager handle :program:`MPD`
shutdown (e.g. :command:`systemctl stop mpd`).
.. _command_password:
:command:`password {PASSWORD}`
This is used for authentication with the server.
``PASSWORD`` is simply the plaintext
password.
.. _command_ping:
:command:`ping`
Does nothing but return "OK".
.. _command_binarylimit:
:command:`binarylimit SIZE` [#since_0_22_4]_
Set the maximum :ref:`binary response <binary>` size for the
current connection to the specified number of bytes.
A bigger value means less overhead for transmitting large
entities, but it also means that the connection is blocked for a
longer time.
.. _command_tagtypes:
:command:`tagtypes`
Shows a list of available tag types. It is an
intersection of the ``metadata_to_use``
@@ -1226,21 +1429,29 @@ Connection settings
``tagtypes`` sub commands configure this
list.
.. _command_tagtypes_disable:
:command:`tagtypes disable {NAME...}`
Remove one or more tags from the list of tag types the
client is interested in. These will be omitted from
responses to this client.
.. _command_tagtypes_enable:
:command:`tagtypes enable {NAME...}`
Re-enable one or more tags from the list of tag types
for this client. These will no longer be hidden from
responses to this client.
.. _command_tagtypes_clear:
:command:`tagtypes clear`
Clear the list of tag types this client is interested
in. This means that :program:`MPD` will
not send any tags to this client.
.. _command_tagtypes_all:
:command:`tagtypes all`
Announce that this client is interested in all tag
types. This is the default setting for new clients.
@@ -1255,34 +1466,50 @@ These commands allow a client to inspect and manage
MPD process: it has separate queue, player and outputs. A
client is assigned to one partition at a time.
.. _command_partition:
:command:`partition {NAME}`
Switch the client to a different partition.
.. _command_listpartitions:
:command:`listpartitions`
Print a list of partitions. Each partition starts with
a ``partition`` keyword and the
partition's name, followed by information about the
partition.
.. _command_newpartition:
:command:`newpartition {NAME}`
Create a new partition.
.. _command_delpartition:
:command:`delpartition {NAME}`
Delete a partition. The partition must be empty (no connected
clients and no outputs).
.. _command_moveoutput:
:command:`moveoutput {OUTPUTNAME}`
Move an output to the current partition.
Audio output devices
====================
.. _command_disableoutput:
:command:`disableoutput {ID}`
Turns an output off.
.. _command_enableoutput:
:command:`enableoutput {ID}`
Turns an output on.
.. _command_toggleoutput:
:command:`toggleoutput {ID}`
Turns an output on or off, depending on the current
state.
@@ -1291,7 +1518,7 @@ Audio output devices
:command:`outputs`
Shows information about all outputs.
::
outputid: 0
@@ -1307,6 +1534,8 @@ Audio output devices
- ``outputname``: Name of the output. It can be any.
- ``outputenabled``: Status of the output. 0 if disabled, 1 if enabled.
.. _command_outputset:
:command:`outputset {ID} {NAME} {VALUE}`
Set a runtime attribute. These are specific to the
output plugin, and supported values are usually printed
@@ -1316,6 +1545,8 @@ Audio output devices
Reflection
==========
.. _command_config:
:command:`config`
Dumps configuration values that may be interesting for
the client. This command is only permitted to "local"
@@ -1325,16 +1556,24 @@ Reflection
- ``music_directory``: The absolute path of the music directory.
.. _command_commands:
:command:`commands`
Shows which commands the current user has access to.
.. _command_notcommands:
:command:`notcommands`
Shows which commands the current user does not have
access to.
.. _command_urlhandlers:
:command:`urlhandlers`
Gets a list of available URL handlers.
.. _command_decoders:
:command:`decoders`
Print a list of decoder plugins, followed by their
supported suffixes and MIME types. Example response::
@@ -1366,12 +1605,16 @@ idle event.
If your MPD instance has multiple partitions, note that
client-to-client messages are local to the current partition.
.. _command_subscribe:
:command:`subscribe {NAME}`
Subscribe to a channel. The channel is created if it
does not exist already. The name may consist of
alphanumeric ASCII characters plus underscore, dash, dot
and colon.
.. _command_unsubscribe:
:command:`unsubscribe {NAME}`
Unsubscribe from a channel.
@@ -1381,10 +1624,14 @@ client-to-client messages are local to the current partition.
Obtain a list of all channels. The response is a list
of "channel:" lines.
.. _command_readmessages:
:command:`readmessages`
Reads messages for this client. The response is a list
of "channel:" and "message:" lines.
.. _command_sendmessage:
:command:`sendmessage {CHANNEL} {TEXT}`
Send a message to the specified channel.
@@ -1393,6 +1640,7 @@ client-to-client messages are local to the current partition.
.. [#since_0_14] Since :program:`MPD` 0.14
.. [#since_0_15] Since :program:`MPD` 0.15
.. [#since_0_16] Since :program:`MPD` 0.16
.. [#since_0_19] Since :program:`MPD` 0.20
.. [#since_0_19] Since :program:`MPD` 0.19
.. [#since_0_20] Since :program:`MPD` 0.20
.. [#since_0_21] Since :program:`MPD` 0.21
.. [#since_0_22_4] Since :program:`MPD` 0.22.4

@@ -55,8 +55,8 @@ and unpack it (or `clone the git repository
In any case, you need:
* a C++17 compiler (e.g. GCC 8 or clang 5)
* `Meson 0.49.0 <http://mesonbuild.com/>`__ and `Ninja
* a C++17 compiler (e.g. GCC 8 or clang 7)
* `Meson 0.56.0 <http://mesonbuild.com/>`__ and `Ninja
<https://ninja-build.org/>`__
* Boost 1.58
* pkg-config
@@ -69,6 +69,7 @@ For example, the following installs a fairly complete list of build dependencies
.. code-block:: none
apt install meson g++ \
libfmt-dev \
libpcre3-dev \
libmad0-dev libmpg123-dev libid3tag0-dev \
libflac-dev libvorbis-dev libopus-dev libogg-dev \
@@ -86,7 +87,7 @@ For example, the following installs a fairly complete list of build dependencies
libpulse-dev libshout3-dev \
libsndio-dev \
libmpdclient-dev \
libnfs-dev libsmbclient-dev \
libnfs-dev \
libupnp-dev \
libavahi-client-dev \
libsqlite3-dev \
@@ -110,6 +111,19 @@ The following command shows a list of compile-time options:
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):
.. code-block:: none
$ meson configure output/release -Dsysconfdir='/etc' ; meson configure output/release |grep syscon
sysconfdir /etc Sysconf data directory
When everything is ready and configured, compile:
.. code-block:: none
@@ -141,6 +155,15 @@ Basically, there are two ways to compile :program:`MPD` for Windows:
This section is about the latter.
You need:
* `mingw-w64 <http://mingw-w64.org/doku.php>`__
* `Meson 0.56.0 <http://mesonbuild.com/>`__ and `Ninja
<https://ninja-build.org/>`__
* cmake
* pkg-config
* quilt
Just like with the native build, unpack the :program:`MPD` source
tarball and change into the directory. Then, instead of
:program:`meson`, type:
@@ -167,7 +190,12 @@ Compiling for Android
You need:
* Android SDK
* Android NDK
* `Android NDK r23 <https://developer.android.com/ndk/downloads>`_
* `Meson 0.56.0 <http://mesonbuild.com/>`__ and `Ninja
<https://ninja-build.org/>`__
* cmake
* pkg-config
* quilt
Just like with the native build, unpack the :program:`MPD` source
tarball and change into the directory. Then, instead of
@@ -413,7 +441,7 @@ The following table lists the audio_output options valid for all plugins:
* - **format samplerate:bits:channels**
- 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.
* - **enabed yes|no**
* - **enabled 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.
* - **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.
@@ -500,6 +528,11 @@ The following table lists the playlist_plugin options valid for all plugins:
- The name of the plugin
* - **enabled yes|no**
- 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`
reference.
@@ -606,13 +639,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`.
* - **add**
- Allows adding songs and loading playlists.
* - **player**
- Allows any player and queue manipulation (start/pause/stop
playback etc.).
* - **control**
- Allows all other player and playlist manipulations.
* - **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:`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.
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.
@@ -622,6 +662,8 @@ Example:
.. code-block:: none
default_permissions "read"
host_permissions "192.168.0.100 read,add,control,admin"
host_permissions "2003:1234:4567::1 read,add,control,admin"
password "the_password@read,add,control"
password "the_admin_password@read,add,control,admin"
@@ -669,6 +711,8 @@ The State File
- Specify the state file location. The parent directory must be writable by the :program:`MPD` user (+wx).
* - **state_file_interval SECONDS**
- 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
^^^^^^^^^^^^^^^^^^^^
@@ -770,6 +814,8 @@ 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).
.. _realtime:
Real-Time Scheduling
--------------------
@@ -1025,12 +1071,20 @@ Check list for bit-perfect playback:
:code:`format`, :ref:`audio_output_format <audio_output_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)
---------------------------
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.
@@ -1091,39 +1145,71 @@ Support
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
^^^^^^^^^^^^^^^
1. Database
"""""""""""
Startup
"""""""
Question: I can't see my music in the MPD database!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Error "could not get realtime scheduling"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
See :ref:`realtime`. You can safely ignore this, but you won't
benefit from real-time scheduling. This only makes a difference if
your computer runs programs other than MPD.
Error "Failed to initialize io_uring"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Linux specific: the io_uring subsystem could not be initialized. This
is not a critical error - MPD will fall back to "classic" blocking
disk I/O. You can safely ignore this error, but you won't benefit
from io_uring's advantages.
* "Cannot allocate memory" usually means that your memlock limit
(``ulimit -l`` in bash or ``LimitMEMLOCK`` in systemd) is too low.
64 MB is a reasonable value for this limit.
* Your Linux kernel might be too old and does not support io_uring.
Error "bind to '0.0.0.0:6600' failed (continuing anyway, because binding to '[::]:6600' succeeded)"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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.
* 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 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.
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.
: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.
@@ -1141,6 +1227,34 @@ Your bug report should contain:
* relevant portions of the log file (:option:`--verbose`)
* 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
^^^^^^^^^^^

@@ -1,18 +1,30 @@
project(
'mpd',
['c', 'cpp'],
version: '0.22',
meson_version: '>= 0.49.0',
version: '0.23.2',
meson_version: '>= 0.56.0',
default_options: [
'c_std=c99',
'build.c_std=c99',
'c_std=c11',
'build.c_std=c11',
'cpp_std=c++17',
'build.cpp_std=c++17',
'warning_level=3',
# This is only here to build subprojects as static libraries; MPD
# itself doesn't ship any libraries.
'default_library=static',
# If we build those libraries as Meson subproject, they shall be
# linked statically into the MPD executable.
'expat:default_library=static',
'fmt:default_library=static',
'gtest:default_library=static',
'sqlite3:default_library=static',
'vorbis:default_library=static',
# Not interested in compiler warnings from subprojects.
'expat:werror=false',
'expat:warning_level=0',
'fmt:warning_level=0',
'gtest:warning_level=0',
'sqlite3:warning_level=0',
'vorbis:warning_level=0',
],
license: 'GPLv2+',
)
@@ -24,15 +36,15 @@ c_compiler = meson.get_compiler('c')
if compiler.get_id() == 'gcc' and compiler.version().version_compare('<8')
warning('Your GCC version is too old. You need at least version 8.')
elif compiler.get_id() == 'clang' and compiler.version().version_compare('<5')
warning('Your clang version is too old. You need at least version 5.')
elif compiler.get_id() == 'clang' and compiler.version().version_compare('<7')
warning('Your clang version is too old. You need at least version 7.')
endif
version_conf = configuration_data()
version_conf.set_quoted('PACKAGE', meson.project_name())
version_conf.set_quoted('PACKAGE_NAME', meson.project_name())
version_conf.set_quoted('VERSION', meson.project_version())
version_conf.set_quoted('PROTOCOL_VERSION', '0.22.0')
version_conf.set_quoted('PROTOCOL_VERSION', '0.23.1')
configure_file(output: 'Version.h', configuration: version_conf)
conf = configuration_data()
@@ -42,68 +54,79 @@ common_cppflags = [
'-D_GNU_SOURCE',
]
common_cflags = [
]
common_cxxflags = [
test_global_common_flags = [
'-fvisibility=hidden',
]
test_common_flags = [
'-Wvla',
'-Wdouble-promotion',
'-fvisibility=hidden',
'-ffast-math',
'-ftree-vectorize',
'-Wcast-qual',
'-Wdouble-promotion',
'-Wmissing-declarations',
'-Wshadow',
'-Wunused',
'-Wvla',
'-Wwrite-strings',
# clang specific warning options:
'-Wunreachable-code-aggressive',
'-Wused-but-marked-unused',
]
test_global_cxxflags = test_global_common_flags + [
]
test_global_cflags = test_global_common_flags + [
]
test_cxxflags = test_common_flags + [
'-fno-threadsafe-statics',
'-fmerge-all-constants',
'-Wmissing-declarations',
'-Wshadow',
'-Wpointer-arith',
'-Wcast-qual',
'-Wwrite-strings',
'-Wsign-compare',
'-Wcomma',
'-Wcomma-subscript',
'-Wextra-semi',
'-Wmismatched-tags',
'-Woverloaded-virtual',
'-Wsign-promo',
'-Wvolatile',
'-Wvirtual-inheritance',
# a vtable without a dtor is just fine
'-Wno-non-virtual-dtor',
# clang specific warning options:
'-Wcomma',
'-Wheader-hygiene',
'-Winconsistent-missing-destructor-override',
'-Wunreachable-code-break',
'-Wunused',
'-Wused-but-marked-unused',
'-Wno-non-virtual-dtor',
]
if compiler.get_id() == 'clang'
# Workaround for clang bug
# https://bugs.llvm.org/show_bug.cgi?id=32611
test_cxxflags += '-funwind-tables'
if compiler.get_id() != 'gcc' or compiler.version().version_compare('>=9')
# The GCC 8 implementation of this flag is buggy: it complains even
# if "final" is present, which implies "override".
test_cxxflags += '-Wsuggest-override'
endif
test_cflags = test_common_flags + [
'-Wmissing-prototypes',
'-Wshadow',
'-Wpointer-arith',
'-Wstrict-prototypes',
'-Wcast-qual',
'-Wwrite-strings',
'-pedantic',
]
test_ldflags = [
# make relocations read-only (hardening)
'-Wl,-z,relro',
# no lazy binding, please - not worth it for a daemon
'-Wl,-z,now',
]
if get_option('buildtype') != 'debug'
test_cxxflags += [
test_global_cxxflags += [
'-ffunction-sections',
'-fdata-sections',
]
test_cflags += [
test_global_cflags += [
'-ffunction-sections',
'-fdata-sections',
]
@@ -112,9 +135,21 @@ if get_option('buildtype') != 'debug'
]
endif
add_global_arguments(common_cxxflags + compiler.get_supported_arguments(test_cxxflags), language: 'cpp')
add_global_arguments(common_cflags + c_compiler.get_supported_arguments(test_cflags), language: 'c')
add_global_link_arguments(compiler.get_supported_link_arguments(test_ldflags), language: 'cpp')
if get_option('fuzzer')
fuzzer_flags = ['-fsanitize=fuzzer']
if get_option('b_sanitize') == 'none'
fuzzer_flags += ['-fsanitize=address,undefined']
endif
add_global_arguments(fuzzer_flags, language: 'cpp')
add_global_arguments(fuzzer_flags, language: 'c')
add_global_link_arguments(fuzzer_flags, language: 'cpp')
endif
add_global_arguments(compiler.get_supported_arguments(test_global_cxxflags), language: 'cpp')
add_global_arguments(c_compiler.get_supported_arguments(test_global_cflags), language: 'c')
add_project_arguments(compiler.get_supported_arguments(test_cxxflags), language: 'cpp')
add_project_arguments(c_compiler.get_supported_arguments(test_cflags), language: 'c')
add_project_link_arguments(compiler.get_supported_link_arguments(test_ldflags), language: 'cpp')
is_linux = host_machine.system() == 'linux'
is_android = get_option('android_ndk') != ''
@@ -128,10 +163,29 @@ endif
if is_windows
common_cppflags += [
'-DWIN32_LEAN_AND_MEAN',
# enable Windows Vista APIs
'-DWINVER=0x0600', '-D_WIN32_WINNT=0x0600',
'-DSTRICT',
# enable Unicode support (TCHAR=wchar_t) in the Windows API (macro
# "UNICODE) and the C library (macro "_UNICODE")
'-DUNICODE', '-D_UNICODE',
# enable strict type checking in the Windows API headers
'-DSTRICT',
# reduce header bloat by disabling obscure and obsolete Windows
# APIs
'-DWIN32_LEAN_AND_MEAN',
# disable more Windows APIs which are not used by MPD
'-DNOGDI', '-DNOBITMAP', '-DNOCOMM',
'-DNOUSER',
# reduce COM header bloat
'-DCOM_NO_WINDOWS_H',
# disable Internet Explorer specific APIs
'-D_WIN32_IE=0',
]
subdir('win32')
@@ -147,8 +201,6 @@ add_global_arguments(common_cppflags, language: 'cpp')
enable_daemon = not is_windows and not is_android and get_option('daemon')
conf.set('ENABLE_DAEMON', enable_daemon)
conf.set('HAVE_CLOCALE', compiler.has_header('clocale'))
conf.set('HAVE_GETPWNAM_R', compiler.has_function('getpwnam_r'))
conf.set('HAVE_GETPWUID_R', compiler.has_function('getpwuid_r'))
conf.set('HAVE_INITGROUPS', compiler.has_function('initgroups'))
@@ -164,17 +216,6 @@ conf.set('HAVE_STRCASESTR', compiler.has_function('strcasestr'))
conf.set('HAVE_PRCTL', is_linux)
conf.set('USE_EVENTFD', is_linux and get_option('eventfd'))
conf.set('USE_SIGNALFD', is_linux and get_option('signalfd'))
if is_windows
conf.set('USE_WINSELECT', true)
elif is_linux and get_option('epoll')
conf.set('USE_EPOLL', true)
else
conf.set('USE_POLL', true)
endif
if not get_option('syslog').disabled()
if compiler.has_function('syslog')
conf.set('HAVE_SYSLOG', true)
@@ -205,24 +246,27 @@ if boost_dep.version() == '1.67'
warning('Your Boost version 1.67 is known to be buggy, and the MPD build will fail. Please upgrade to Boost 1.68 or later.')
endif
fmt_dep = dependency('fmt', fallback: ['fmt', 'fmt_dep'])
log = static_library(
'log',
'src/Log.cxx',
'src/LogBackend.cxx',
include_directories: inc,
dependencies: fmt_dep,
)
log_dep = declare_dependency(
link_with: log,
dependencies: fmt_dep,
)
sources = [
version_cxx,
'src/Main.cxx',
'src/protocol/Ack.cxx',
'src/protocol/ArgParser.cxx',
'src/protocol/Result.cxx',
'src/command/CommandError.cxx',
'src/command/PositionArg.cxx',
'src/command/AllCommands.cxx',
'src/command/QueueCommands.cxx',
'src/command/TagCommands.cxx',
@@ -237,7 +281,6 @@ sources = [
'src/command/CommandListBuilder.cxx',
'src/Idle.cxx',
'src/IdleFlags.cxx',
'src/decoder/Domain.cxx',
'src/decoder/Thread.cxx',
'src/decoder/Control.cxx',
'src/decoder/Bridge.cxx',
@@ -263,7 +306,6 @@ sources = [
'src/LogInit.cxx',
'src/ls.cxx',
'src/Instance.cxx',
'src/win32/Win32Main.cxx',
'src/MusicBuffer.cxx',
'src/MusicPipe.cxx',
'src/MusicChunk.cxx',
@@ -311,6 +353,12 @@ sources = [
'src/PlaylistFile.cxx',
]
if is_windows
sources += [
'src/win32/Win32Main.cxx',
]
endif
if not is_android
sources += [
'src/CommandLine.cxx',
@@ -345,6 +393,7 @@ subdir('src/system')
subdir('src/thread')
subdir('src/net')
subdir('src/event')
subdir('src/win32')
subdir('src/apple')
@@ -362,6 +411,7 @@ subdir('src/lib/gcrypt')
subdir('src/lib/nfs')
subdir('src/lib/oss')
subdir('src/lib/pcre')
subdir('src/lib/pipewire')
subdir('src/lib/pulse')
subdir('src/lib/sndio')
subdir('src/lib/sqlite')
@@ -371,6 +421,8 @@ subdir('src/lib/yajl')
subdir('src/lib/crypto')
subdir('src/zeroconf')
subdir('src/fs')
subdir('src/config')
subdir('src/tag')
@@ -386,7 +438,6 @@ subdir('src/decoder')
subdir('src/encoder')
subdir('src/song')
subdir('src/playlist')
subdir('src/zeroconf')
if curl_dep.found()
sources += 'src/RemoteTagCache.cxx'
@@ -502,8 +553,10 @@ mpd = build_target(
zeroconf_dep,
more_deps,
chromaprint_dep,
fmt_dep,
],
link_args: link_args,
build_by_default: not get_option('fuzzer'),
install: not is_android and not is_haiku,
)
@@ -544,3 +597,7 @@ subdir('doc')
if get_option('test')
subdir('test')
endif
if get_option('fuzzer')
subdir('test/fuzzer')
endif

@@ -2,8 +2,6 @@ option('documentation', type: 'feature', description: 'Build documentation')
option('html_manual', type: 'boolean', value: true, description: 'Build the HTML manual')
option('manpages', type: 'boolean', value: true, description: 'Build manual pages')
option('test', type: 'boolean', value: false, description: 'Build the unit tests and debug programs')
option('syslog', type: 'feature', description: 'syslog support')
option('inotify', type: 'boolean', value: true, description: 'inotify support (for automatic database update)')
option('io_uring', type: 'feature', description: 'Linux io_uring support using liburing')
@@ -14,6 +12,13 @@ option('systemd', type: 'feature', description: 'systemd support')
option('systemd_system_unit_dir', type: 'string', description: 'systemd system service directory')
option('systemd_user_unit_dir', type: 'string', description: 'systemd user service directory')
#
# Options for developers
#
option('test', type: 'boolean', value: false, description: 'Build the unit tests and debug programs')
option('fuzzer', type: 'boolean', value: false, description: 'Build fuzzers (requires libFuzzer)')
#
# Android
#
@@ -57,7 +62,10 @@ option('dsd', type: 'boolean', value: true, description: 'Support the DSD audio
#
option('database', type: 'boolean', value: true, description: 'enable support for the music database')
option('upnp', type: 'feature', description: 'UPnP client support')
option('upnp', type: 'combo',
choices: ['auto', 'pupnp', 'npupnp', 'disabled'],
value: 'auto',
description: 'UPnP client support')
option('libmpdclient', type: 'feature', description: 'libmpdclient support (for the proxy database plugin)')
#
@@ -87,7 +95,11 @@ option('cdio_paranoia', type: 'feature', description: 'libcdio_paranoia input pl
option('curl', type: 'feature', description: 'HTTP client using CURL')
option('mms', type: 'feature', description: 'MMS protocol support using libmms')
option('nfs', type: 'feature', description: 'NFS protocol support using libnfs')
option('smbclient', type: 'feature', description: 'SMB support using libsmbclient')
# The "smbclient" plugin is disabled by default because libsmbclient
# has a serious bug which crashes MPD very quickly:
# https://bugzilla.samba.org/show_bug.cgi?id=11413
option('smbclient', type: 'feature', value: 'disabled', description: 'SMB support using libsmbclient')
#
# Commercial services
@@ -95,7 +107,6 @@ option('smbclient', type: 'feature', description: 'SMB support using libsmbclien
option('qobuz', type: 'feature', description: 'Qobuz client')
option('soundcloud', type: 'feature', description: 'SoundCloud client')
option('tidal', type: 'feature', description: 'Tidal client')
#
# Archive plugins
@@ -126,6 +137,7 @@ option('gme', type: 'feature', description: 'Game Music Emulator decoder plugin'
option('mad', type: 'feature', description: 'MP3 decoder using libmad')
option('mikmod', type: 'feature', description: 'MikMod decoder plugin')
option('modplug', type: 'feature', description: 'Modplug decoder plugin')
option('openmpt', type: 'feature', description: 'OpenMPT decoder plugin')
option('mpcdec', type: 'feature', description: 'Musepack decoder plugin')
option('mpg123', type: 'feature', description: 'MP3 decoder using libmpg123')
option('opus', type: 'feature', description: 'Opus decoder plugin')
@@ -165,9 +177,11 @@ option('jack', type: 'feature', description: 'JACK output plugin')
option('openal', type: 'feature', description: 'OpenAL output plugin')
option('oss', type: 'feature', description: 'Open Sound System support')
option('pipe', type: 'boolean', value: true, description: 'Pipe output plugin')
option('pipewire', type: 'feature', description: 'PipeWire support')
option('pulse', type: 'feature', description: 'PulseAudio support')
option('recorder', type: 'boolean', value: true, description: 'Recorder output plugin')
option('shout', type: 'feature', description: 'Shoutcast streaming support using libshout')
option('snapcast', type: 'boolean', value: true, description: 'Snapcast output plugin')
option('sndio', type: 'feature', description: 'sndio output plugin')
option('solaris_output', type: 'feature', description: 'Solaris /dev/audio support')

@@ -55,10 +55,10 @@ class AutotoolsProject(MakeProject):
subprocess.check_call(configure, cwd=build, env=toolchain.env)
return build
def build(self, toolchain):
def _build(self, toolchain):
build = self.configure(toolchain)
if self.subdirs is not None:
for subdir in self.subdirs:
MakeProject.build(self, toolchain, os.path.join(build, subdir))
self.build_make(toolchain, os.path.join(build, subdir))
else:
MakeProject.build(self, toolchain, build)
self.build_make(toolchain, build)

@@ -12,7 +12,7 @@ class BoostProject(Project):
name='boost', version=version,
**kwargs)
def build(self, toolchain):
def _build(self, toolchain):
src = self.unpack(toolchain)
# install the headers manually; don't build any library
@@ -21,3 +21,8 @@ class BoostProject(Project):
dest = os.path.join(includedir, 'boost')
shutil.rmtree(dest, ignore_errors=True)
shutil.copytree(os.path.join(src, 'boost'), dest)
# touch the boost/version.hpp file to ensure it's newer than
# the downloaded Boost tarball, to avoid reinstalling Boost on
# every run
os.utime(os.path.join(toolchain.install_prefix, self.installed))

@@ -1,27 +1,63 @@
import os
import subprocess
from build.project import Project
def __write_cmake_compiler(f, language, compiler):
s = compiler.split(' ', 1)
if len(s) == 2:
print(f'set(CMAKE_{language}_COMPILER_LAUNCHER {s[0]})', file=f)
compiler = s[1]
print(f'set(CMAKE_{language}_COMPILER {compiler})', file=f)
def __write_cmake_toolchain_file(f, toolchain):
if '-darwin' in toolchain.actual_arch:
cmake_system_name = 'Darwin'
elif toolchain.is_windows:
cmake_system_name = 'Windows'
else:
cmake_system_name = 'Linux'
f.write(f"""
set(CMAKE_SYSTEM_NAME {cmake_system_name})
set(CMAKE_SYSTEM_PROCESSOR {toolchain.actual_arch.split('-', 1)[0]})
set(CMAKE_C_COMPILER_TARGET {toolchain.actual_arch})
set(CMAKE_CXX_COMPILER_TARGET {toolchain.actual_arch})
set(CMAKE_C_FLAGS "{toolchain.cflags} {toolchain.cppflags}")
set(CMAKE_CXX_FLAGS "{toolchain.cxxflags} {toolchain.cppflags}")
""")
__write_cmake_compiler(f, 'C', toolchain.cc)
__write_cmake_compiler(f, 'CXX', toolchain.cxx)
def configure(toolchain, src, build, args=()):
cross_args = []
if toolchain.is_windows:
cross_args.append('-DCMAKE_SYSTEM_NAME=Windows')
cross_args.append('-DCMAKE_RC_COMPILER=' + toolchain.windres)
# Several targets need a sysroot to prevent pkg-config from
# looking for libraries on the build host (TODO: fix this
# properly); but we must not do that on Android because the NDK
# has a sysroot already
if '-android' not in toolchain.actual_arch and '-darwin' not in toolchain.actual_arch:
cross_args.append('-DCMAKE_SYSROOT=' + toolchain.install_prefix)
os.makedirs(build, exist_ok=True)
cmake_toolchain_file = os.path.join(build, 'cmake_toolchain_file')
with open(cmake_toolchain_file, 'w') as f:
__write_cmake_toolchain_file(f, toolchain)
configure = [
'cmake',
src,
'-DCMAKE_TOOLCHAIN_FILE=' + cmake_toolchain_file,
'-DCMAKE_INSTALL_PREFIX=' + toolchain.install_prefix,
'-DCMAKE_BUILD_TYPE=release',
'-DCMAKE_C_COMPILER=' + toolchain.cc,
'-DCMAKE_CXX_COMPILER=' + toolchain.cxx,
'-DCMAKE_C_FLAGS=' + toolchain.cflags + ' ' + toolchain.cppflags,
'-DCMAKE_CXX_FLAGS=' + toolchain.cxxflags + ' ' + toolchain.cppflags,
'-GNinja',
] + cross_args + args
@@ -29,17 +65,22 @@ def configure(toolchain, src, build, args=()):
class CmakeProject(Project):
def __init__(self, url, md5, installed, configure_args=[],
windows_configure_args=[],
**kwargs):
Project.__init__(self, url, md5, installed, **kwargs)
self.configure_args = configure_args
self.windows_configure_args = windows_configure_args
def configure(self, toolchain):
src = self.unpack(toolchain)
build = self.make_build_path(toolchain)
configure(toolchain, src, build, self.configure_args)
configure_args = self.configure_args
if toolchain.is_windows:
configure_args = configure_args + self.windows_configure_args
configure(toolchain, src, build, configure_args)
return build
def build(self, toolchain):
def _build(self, toolchain):
build = self.configure(toolchain)
subprocess.check_call(['ninja', 'install'],
cwd=build, env=toolchain.env)

@@ -10,12 +10,7 @@ class FfmpegProject(Project):
self.configure_args = configure_args
self.cppflags = cppflags
def _filter_cflags(self, flags):
# FFmpeg expects the GNU as syntax
flags = flags.replace(' -integrated-as ', ' -no-integrated-as ')
return flags
def build(self, toolchain):
def _build(self, toolchain):
src = self.unpack(toolchain)
build = self.make_build_path(toolchain)
@@ -36,8 +31,8 @@ class FfmpegProject(Project):
'--cc=' + toolchain.cc,
'--cxx=' + toolchain.cxx,
'--nm=' + toolchain.nm,
'--extra-cflags=' + self._filter_cflags(toolchain.cflags) + ' ' + toolchain.cppflags + ' ' + self.cppflags,
'--extra-cxxflags=' + self._filter_cflags(toolchain.cxxflags) + ' ' + toolchain.cppflags + ' ' + self.cppflags,
'--extra-cflags=' + toolchain.cflags + ' ' + toolchain.cppflags + ' ' + self.cppflags,
'--extra-cxxflags=' + toolchain.cxxflags + ' ' + toolchain.cppflags + ' ' + self.cppflags,
'--extra-ldflags=' + toolchain.ldflags,
'--extra-libs=' + toolchain.libs,
'--ar=' + toolchain.ar,

47
python/build/jack.py Normal file

@@ -0,0 +1,47 @@
import os, shutil
import re
from .project import Project
# This class installs just the public headers and a fake pkg-config
# file which defines the macro "DYNAMIC_JACK". This tells MPD's JACK
# output plugin to load the libjack64.dll dynamically using
# LoadLibrary(). This kludge avoids the runtime DLL dependency for
# users who don't use JACK, but still allows using the system JACK
# client library.
#
# The problem with JACK is that it uses an extremely fragile shared
# memory protocol to communicate with the daemon. One needs to use
# daemon and client library from the same build. That's why we don't
# build libjack statically here; it would probably not be compatible
# with the user's JACK daemon.
class JackProject(Project):
def __init__(self, url, md5, installed,
**kwargs):
m = re.match(r'.*/v([\d.]+)\.tar\.gz$', url)
self.version = m.group(1)
Project.__init__(self, url, md5, installed,
name='jack2', version=self.version,
base='jack2-' + self.version,
**kwargs)
def _build(self, toolchain):
src = self.unpack(toolchain)
includes = ['jack.h', 'ringbuffer.h', 'systemdeps.h', 'transport.h', 'types.h', 'weakmacros.h']
includedir = os.path.join(toolchain.install_prefix, 'include', 'jack')
os.makedirs(includedir, exist_ok=True)
for i in includes:
shutil.copyfile(os.path.join(src, 'common', 'jack', i),
os.path.join(includedir, i))
with open(os.path.join(toolchain.install_prefix, 'lib', 'pkgconfig', 'jack.pc'), 'w') as f:
print("prefix=" + toolchain.install_prefix, file=f)
print("", file=f)
print("Name: jack", file=f)
print("Description: dummy", file=f)
print("Version: " + self.version, file=f)
print("Libs: ", file=f)
print("Cflags: -DDYNAMIC_JACK", file=f)

@@ -7,7 +7,9 @@ from build.meson import MesonProject
from build.cmake import CmakeProject
from build.autotools import AutotoolsProject
from build.ffmpeg import FfmpegProject
from build.openssl import OpenSSLProject
from build.boost import BoostProject
from build.jack import JackProject
libmpdclient = MesonProject(
'https://www.musicpd.org/download/libmpdclient/2/libmpdclient-2.19.tar.xz',
@@ -15,29 +17,17 @@ libmpdclient = MesonProject(
'lib/libmpdclient.a',
)
libogg = AutotoolsProject(
libogg = CmakeProject(
'http://downloads.xiph.org/releases/ogg/libogg-1.3.4.tar.xz',
'c163bc12bc300c401b6aa35907ac682671ea376f13ae0969a220f7ddf71893fe',
'lib/libogg.a',
[
'--disable-shared', '--enable-static',
'-DBUILD_SHARED_LIBS=OFF',
'-DINSTALL_DOCS=OFF',
'-DINSTALL_CMAKE_PACKAGE_MODULE=OFF',
],
)
libvorbis = AutotoolsProject(
'http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.7.tar.xz',
'b33cc4934322bcbf6efcbacf49e3ca01aadbea4114ec9589d1b1e9d20f72954b',
'lib/libvorbis.a',
[
'--disable-shared', '--enable-static',
],
edits={
# this option is not understood by clang
'configure': lambda data: data.replace('-mno-ieee-fp', ' '),
}
)
opus = AutotoolsProject(
'https://archive.mozilla.org/pub/opus/opus-1.3.1.tar.gz',
'65b58e1e25b2a114157014736a3d9dfeaad8d41be1c8179866f144a2fb44ff9d',
@@ -121,18 +111,27 @@ libmodplug = AutotoolsProject(
],
)
libopenmpt = AutotoolsProject(
'https://lib.openmpt.org/files/libopenmpt/src/libopenmpt-0.5.8+release.autotools.tar.gz',
'61de7cc0c011b10472ca16adcc123689',
'lib/libopenmpt.a',
[
'--disable-shared', '--enable-static'
],
)
wildmidi = CmakeProject(
'https://codeload.github.com/Mindwerks/wildmidi/tar.gz/wildmidi-0.4.3',
'498e5a96455bb4b91b37188ad6dcb070824e92c44f5ed452b90adbaec8eef3c5',
'https://codeload.github.com/Mindwerks/wildmidi/tar.gz/wildmidi-0.4.4',
'6f267c8d331e9859906837e2c197093fddec31829d2ebf7b958cf6b7ae935430',
'lib/libWildMidi.a',
[
'-DBUILD_SHARED_LIBS=OFF',
'-DWANT_PLAYER=OFF',
'-DWANT_STATIC=ON',
],
base='wildmidi-wildmidi-0.4.3',
base='wildmidi-wildmidi-0.4.4',
name='wildmidi',
version='0.4.3',
version='0.4.4',
)
gme = CmakeProject(
@@ -148,8 +147,8 @@ gme = CmakeProject(
)
ffmpeg = FfmpegProject(
'http://ffmpeg.org/releases/ffmpeg-4.3.1.tar.xz',
'ad009240d46e307b4e03a213a0f49c11b650e445b1f8be0dda2a9212b34d2ffb',
'http://ffmpeg.org/releases/ffmpeg-4.4.tar.xz',
'06b10a183ce5371f915c6bb15b7b1fffbe046e8275099c96affc29e17645d909',
'lib/libavcodec.a',
[
'--disable-shared', '--enable-static',
@@ -376,43 +375,45 @@ ffmpeg = FfmpegProject(
],
)
curl = AutotoolsProject(
'http://curl.haxx.se/download/curl-7.72.0.tar.xz',
'0ded0808c4d85f2ee0db86980ae610cc9d165e9ca9da466196cc73c346513713',
'lib/libcurl.a',
[
'--disable-shared', '--enable-static',
'--disable-debug',
'--enable-http',
'--enable-ipv6',
'--disable-ftp', '--disable-file',
'--disable-ldap', '--disable-ldaps',
'--disable-rtsp', '--disable-proxy', '--disable-dict', '--disable-telnet',
'--disable-tftp', '--disable-pop3', '--disable-imap', '--disable-smtp',
'--disable-smb',
'--disable-gopher',
'--disable-manual',
'--disable-threaded-resolver', '--disable-verbose', '--disable-sspi',
'--disable-crypto-auth', '--disable-ntlm-wb', '--disable-tls-srp', '--disable-cookies',
'--disable-doh',
'--disable-mime',
'--disable-netrc',
'--disable-progress-meter',
'--disable-alt-svc',
'--without-ssl', '--without-gnutls', '--without-nss', '--without-libssh2',
],
patches='src/lib/curl/patches',
openssl = OpenSSLProject(
'https://www.openssl.org/source/openssl-3.0.0.tar.gz',
'59eedfcb46c25214c9bd37ed6078297b4df01d012267fe9e9eee31f61bc70536',
'include/openssl/ossl_typ.h',
)
libexpat = AutotoolsProject(
'https://github.com/libexpat/libexpat/releases/download/R_2_2_9/expat-2.2.9.tar.bz2',
'f1063084dc4302a427dabcca499c8312b3a32a29b7d2506653ecc8f950a9a237',
'lib/libexpat.a',
curl = CmakeProject(
'https://curl.se/download/curl-7.79.1.tar.xz',
'0606f74b1182ab732a17c11613cbbaf7084f2e6cca432642d0e3ad7c224c3689',
'lib/libcurl.a',
[
'--disable-shared', '--enable-static',
'--without-docbook',
'-DBUILD_CURL_EXE=OFF',
'-DBUILD_SHARED_LIBS=OFF',
'-DCURL_DISABLE_VERBOSE_STRINGS=ON',
'-DCURL_DISABLE_LDAP=ON',
'-DCURL_DISABLE_TELNET=ON',
'-DCURL_DISABLE_DICT=ON',
'-DCURL_DISABLE_FILE=ON',
'-DCURL_DISABLE_FTP=ON',
'-DCURL_DISABLE_TFTP=ON',
'-DCURL_DISABLE_LDAPS=ON',
'-DCURL_DISABLE_RTSP=ON',
'-DCURL_DISABLE_PROXY=ON',
'-DCURL_DISABLE_POP3=ON',
'-DCURL_DISABLE_IMAP=ON',
'-DCURL_DISABLE_SMTP=ON',
'-DCURL_DISABLE_GOPHER=ON',
'-DCURL_DISABLE_COOKIES=ON',
'-DCURL_DISABLE_CRYPTO_AUTH=ON',
'-DCURL_DISABLE_ALTSVC=ON',
'-DCMAKE_USE_LIBSSH2=OFF',
'-DCURL_WINDOWS_SSPI=OFF',
'-DCURL_DISABLE_NTLM=ON',
'-DBUILD_TESTING=OFF',
],
windows_configure_args=[
'-DCMAKE_USE_SCHANNEL=ON',
],
patches='src/lib/curl/patches',
)
libnfs = AutotoolsProject(
@@ -429,11 +430,18 @@ libnfs = AutotoolsProject(
'--disable-utils', '--disable-examples',
],
base='libnfs-libnfs-4.0.0',
patches='src/lib/nfs/patches',
autoreconf=True,
)
jack = JackProject(
'https://github.com/jackaudio/jack2/archive/v1.9.17.tar.gz',
'38f674bbc57852a8eb3d9faa1f96a0912d26f7d5df14c11005ad499c8ae352f2',
'lib/pkgconfig/jack.pc',
)
boost = BoostProject(
'https://dl.bintray.com/boostorg/release/1.74.0/source/boost_1_74_0.tar.bz2',
'83bfc1507731a0906e387fc28b7ef5417d591429e51e788417fe9ff025e116b1',
'https://boostorg.jfrog.io/artifactory/main/release/1.77.0/source/boost_1_77_0.tar.bz2',
'fc9f85fc030e233142908241af7a846e60630aa7388de9a5fafb1f3a26840854',
'include/boost/version.hpp',
)

@@ -22,7 +22,7 @@ class MakeProject(Project):
subprocess.check_call(['/usr/bin/make'] + args,
cwd=wd, env=toolchain.env)
def build(self, toolchain, wd, install=True):
def build_make(self, toolchain, wd, install=True):
self.make(toolchain, wd, self.get_make_args(toolchain))
if install:
self.make(toolchain, wd, self.get_make_install_args(toolchain))

@@ -1,4 +1,5 @@
import os.path, subprocess, sys
import platform
from build.project import Project
@@ -34,41 +35,46 @@ def make_cross_file(toolchain):
path = os.path.join(toolchain.build_path, 'meson.cross')
os.makedirs(toolchain.build_path, exist_ok=True)
with open(path, 'w') as f:
f.write("""
f.write(f"""
[binaries]
c = '%s'
cpp = '%s'
ar = '%s'
strip = '%s'
pkgconfig = '%s'
%s
c = '{toolchain.cc}'
cpp = '{toolchain.cxx}'
ar = '{toolchain.ar}'
strip = '{toolchain.strip}'
pkgconfig = '{toolchain.pkg_config}'
""")
if toolchain.is_windows and platform.system() != 'Windows':
f.write(f"windres = '{toolchain.windres}'\n")
# Run unit tests with WINE when cross-building for Windows
print("exe_wrapper = 'wine'", file=f)
f.write(f"""
[properties]
root = '%s'
root = '{toolchain.install_prefix}'
c_args = %s
c_link_args = %s
[built-in options]
c_args = {repr((toolchain.cppflags + ' ' + toolchain.cflags).split())}
c_link_args = {repr(toolchain.ldflags.split() + toolchain.libs.split())}
cpp_args = %s
cpp_link_args = %s
cpp_args = {repr((toolchain.cppflags + ' ' + toolchain.cxxflags).split())}
cpp_link_args = {repr(toolchain.ldflags.split() + toolchain.libs.split())}
""")
if 'android' in toolchain.arch:
f.write("""
# Keep Meson from executing Android-x86 test binariees
needs_exe_wrapper = true
""")
f.write(f"""
[host_machine]
system = '%s'
cpu_family = '%s'
cpu = '%s'
endian = '%s'
""" % (toolchain.cc, toolchain.cxx, toolchain.ar, toolchain.strip,
toolchain.pkg_config,
windres,
toolchain.install_prefix,
repr((toolchain.cppflags + ' ' + toolchain.cflags).split()),
repr(toolchain.ldflags.split() + toolchain.libs.split()),
repr((toolchain.cppflags + ' ' + toolchain.cxxflags).split()),
repr(toolchain.ldflags.split() + toolchain.libs.split()),
system, cpu_family, cpu, endian))
system = '{system}'
cpu_family = '{cpu_family}'
cpu = '{cpu}'
endian = '{endian}'
""")
return path
def configure(toolchain, src, build, args=()):
@@ -79,11 +85,6 @@ def configure(toolchain, src, build, args=()):
'--prefix', toolchain.install_prefix,
# this is necessary because Meson uses Debian's build machine
# MultiArch path (e.g. "lib/x86_64-linux-gnu") for cross
# builds, which is obviously wrong
'--libdir', 'lib',
'--buildtype', 'plain',
'--default-library=static',
@@ -110,7 +111,7 @@ class MesonProject(Project):
configure(toolchain, src, build, self.configure_args)
return build
def build(self, toolchain):
def _build(self, toolchain):
build = self.configure(toolchain)
subprocess.check_call(['ninja', 'install'],
cwd=build, env=toolchain.env)

61
python/build/openssl.py Normal file

@@ -0,0 +1,61 @@
import subprocess
from build.makeproject import MakeProject
class OpenSSLProject(MakeProject):
def __init__(self, url, md5, installed,
**kwargs):
MakeProject.__init__(self, url, md5, installed, install_target='install_dev', **kwargs)
def get_make_args(self, toolchain):
return MakeProject.get_make_args(self, toolchain) + [
'CC=' + toolchain.cc,
'CFLAGS=' + toolchain.cflags,
'CPPFLAGS=' + toolchain.cppflags,
'AR=' + toolchain.ar,
'RANLIB=' + toolchain.ranlib,
'build_libs',
]
def get_make_install_args(self, toolchain):
# OpenSSL's Makefile runs "ranlib" during installation
return MakeProject.get_make_install_args(self, toolchain) + [
'RANLIB=' + toolchain.ranlib,
]
def _build(self, toolchain):
src = self.unpack(toolchain, out_of_tree=False)
# OpenSSL has a weird target architecture scheme with lots of
# hard-coded architectures; this table translates between our
# "toolchain_arch" (HOST_TRIPLET) and the OpenSSL target
openssl_archs = {
# not using "android-*" because those OpenSSL targets want
# to know where the SDK is, but our own build scripts
# prepared everything already to look like a regular Linux
# build
'arm-linux-androideabi': 'linux-generic32',
'aarch64-linux-android': 'linux-aarch64',
'i686-linux-android': 'linux-x86-clang',
'x86_64-linux-android': 'linux-x86_64-clang',
# Kobo
'arm-linux-gnueabihf': 'linux-generic32',
# Windows
'i686-w64-mingw32': 'mingw',
'x86_64-w64-mingw32': 'mingw64',
}
openssl_arch = openssl_archs[toolchain.arch]
subprocess.check_call(['./Configure',
'no-shared',
'no-module', 'no-engine', 'no-static-engine',
'no-async',
'no-tests',
'no-asm', # "asm" causes build failures on Windows
openssl_arch,
'--prefix=' + toolchain.install_prefix],
cwd=src, env=toolchain.env)
self.build_make(toolchain, src)

@@ -20,7 +20,7 @@ class Project:
self.base = base
if name is None or version is None:
m = re.match(r'^([-\w]+)-(\d[\d.]*[a-z]?[\d.]*)$', self.base)
m = re.match(r'^([-\w]+)-(\d[\d.]*[a-z]?[\d.]*(?:-(?:alpha|beta)\d+)?)(\+.*)?$', self.base)
if name is None: name = m.group(1)
if version is None: version = m.group(2)
@@ -79,3 +79,6 @@ class Project:
pass
os.makedirs(path, exist_ok=True)
return path
def build(self, toolchain):
self._build(toolchain)

@@ -31,6 +31,8 @@ def guess_digest_algorithm(digest):
return hashlib.sha1
elif l == 64:
return hashlib.sha256
elif l == 128:
return hashlib.sha512
else:
return None

@@ -7,7 +7,7 @@ class ZlibProject(Project):
**kwargs):
Project.__init__(self, url, md5, installed, **kwargs)
def build(self, toolchain):
def _build(self, toolchain):
src = self.unpack(toolchain, out_of_tree=False)
subprocess.check_call(['/usr/bin/make', '--quiet',

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -37,6 +37,7 @@
#include "fs/Traits.hxx"
#include "fs/FileSystem.hxx"
#include "fs/StandardDirectory.hxx"
#include "event/Features.h"
#include "io/uring/Features.h"
#include "util/Domain.hxx"
#include "util/OptionDef.hxx"
@@ -113,7 +114,7 @@ static void version()
printf("Music Player Daemon " VERSION " (%s)"
"\n"
"Copyright 2003-2007 Warren Dukes <warren.dukes@gmail.com>\n"
"Copyright 2008-2018 Max Kellermann <max.kellermann@gmail.com>\n"
"Copyright 2008-2021 Max Kellermann <max.kellermann@gmail.com>\n"
"This is free software; see the source for copying conditions. There is NO\n"
"warranty; not even MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
GIT_VERSION);

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -27,7 +27,7 @@
#include <cassert>
static const char *const idle_names[] = {
static constexpr const char * idle_names[] = {
"database",
"stored_playlist",
"playlist",
@@ -42,7 +42,7 @@ static const char *const idle_names[] = {
"neighbor",
"mount",
"partition",
nullptr
nullptr,
};
const char*const*

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -25,8 +25,6 @@
#ifndef MPD_IDLE_FLAGS_HXX
#define MPD_IDLE_FLAGS_HXX
#include "util/Compiler.h"
/** song database has been updated*/
static constexpr unsigned IDLE_DATABASE = 0x1;
@@ -73,7 +71,7 @@ static constexpr unsigned IDLE_PARTITION = 0x2000;
/**
* Get idle names
*/
gcc_const
[[gnu::const]]
const char*const*
idle_get_names() noexcept;
@@ -81,7 +79,7 @@ idle_get_names() noexcept;
* Parse an idle name and return its mask. Returns 0 if the given
* name is unknown.
*/
gcc_nonnull_all gcc_pure
[[gnu::nonnull]] [[gnu::pure]]
unsigned
idle_parse_name(const char *name) noexcept;

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -37,6 +37,10 @@
#include "db/update/Service.hxx"
#include "storage/StorageInterface.hxx"
#ifdef ENABLE_INOTIFY
#include "db/update/InotifyUpdate.hxx"
#endif
#ifdef ENABLE_NEIGHBOR_PLUGINS
#include "neighbor/Glue.hxx"
#endif

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -24,7 +24,6 @@
#include "event/Loop.hxx"
#include "event/Thread.hxx"
#include "event/MaskMonitor.hxx"
#include "util/Compiler.h"
#ifdef ENABLE_SYSTEMD_DAEMON
#include "lib/systemd/Watchdog.hxx"
@@ -44,6 +43,9 @@ class NeighborGlue;
#include "db/Ptr.hxx"
class Storage;
class UpdateService;
#ifdef ENABLE_INOTIFY
class InotifyUpdate;
#endif
#endif
#include <memory>
@@ -121,6 +123,10 @@ struct Instance final
Storage *storage = nullptr;
UpdateService *update = nullptr;
#ifdef ENABLE_INOTIFY
std::unique_ptr<InotifyUpdate> inotify_update;
#endif
#endif
#ifdef ENABLE_CURL
@@ -168,7 +174,7 @@ struct Instance final
* Find a #Partition with the given name. Returns nullptr if
* no such partition was found.
*/
gcc_pure
[[gnu::pure]]
Partition *FindPartition(const char *name) noexcept;
void DeletePartition(Partition &partition) noexcept;
@@ -194,7 +200,7 @@ struct Instance final
#endif
#ifdef ENABLE_SQLITE
bool HasStickerDatabase() noexcept {
bool HasStickerDatabase() const noexcept {
return sticker_database != nullptr;
}
#endif

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -25,13 +25,16 @@
#include "config/Data.hxx"
#include "config/Option.hxx"
#include "config/Net.hxx"
#include "lib/fmt/ExceptionFormatter.hxx"
#include "lib/fmt/PathFormatter.hxx"
#include "net/AllocatedSocketAddress.hxx"
#include "net/UniqueSocketDescriptor.hxx"
#include "net/SocketUtil.hxx"
#include "system/Error.hxx"
#include "util/RuntimeError.hxx"
#include "fs/AllocatedPath.hxx"
#include "fs/XDG.hxx"
#include "util/Domain.hxx"
#include "util/RuntimeError.hxx"
#include <sys/stat.h>
@@ -41,6 +44,10 @@
#define DEFAULT_PORT 6600
#if defined(USE_XDG) && defined(HAVE_UN)
static constexpr Domain listen_domain("listen");
#endif
int listen_port;
#ifdef ENABLE_SYSTEMD_DAEMON
@@ -98,9 +105,9 @@ ListenXdgRuntimeDir(ClientListener &listener) noexcept
listener.AddFD(std::move(fd), std::move(address));
return true;
} catch (...) {
FormatError(std::current_exception(),
"Failed to listen on '%s' (not fatal)",
socket_path.c_str());
FmtError(listen_domain,
"Failed to listen on '{}' (not fatal): {}",
socket_path, std::current_exception());
return false;
}
#else

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -22,6 +22,7 @@
#include "client/Client.hxx"
#include "fs/AllocatedPath.hxx"
#include "ls.hxx"
#include "storage/Registry.hxx"
#include "util/ASCII.hxx"
#include "util/UriExtract.hxx"
@@ -67,9 +68,13 @@ LocateAbsoluteUri(UriPluginKind kind, const char *uri
{
switch (kind) {
case UriPluginKind::INPUT:
case UriPluginKind::STORAGE: // TODO: separate check for storage plugins
if (!uri_supported_scheme(uri))
throw std::runtime_error("Unsupported URI scheme");
throw std::invalid_argument("Unsupported URI scheme");
break;
case UriPluginKind::STORAGE:
/* plugin support will be checked after the
Storage::MapToRelativeUTF8() call */
break;
case UriPluginKind::PLAYLIST:
@@ -88,6 +93,10 @@ LocateAbsoluteUri(UriPluginKind kind, const char *uri
return LocatedUri(LocatedUri::Type::RELATIVE,
suffix.data());
}
if (kind == UriPluginKind::STORAGE &&
GetStoragePluginByUri(uri) == nullptr)
throw std::invalid_argument("Unsupported URI scheme");
#endif
return LocatedUri(LocatedUri::Type::ABSOLUTE, uri);
@@ -105,7 +114,7 @@ LocateUri(UriPluginKind kind,
const char *path_utf8 = StringAfterPrefixCaseASCII(uri, "file://");
if (path_utf8 != nullptr) {
if (!PathTraitsUTF8::IsAbsolute(path_utf8))
throw std::runtime_error("Malformed file:// URI");
throw std::invalid_argument("Malformed file:// URI");
return LocateFileUri(path_utf8, client
#ifdef ENABLE_DATABASE

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -17,166 +17,35 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "LogV.hxx"
#include "Log.hxx"
#include "lib/fmt/ExceptionFormatter.hxx"
#include "util/Domain.hxx"
#include "util/Exception.hxx"
#include <cerrno>
#include <stdio.h>
#include <string.h>
#include <fmt/format.h>
static constexpr Domain exception_domain("exception");
void
LogFormatV(LogLevel level, const Domain &domain,
const char *fmt, std::va_list ap) noexcept
LogVFmt(LogLevel level, const Domain &domain,
fmt::string_view format_str, fmt::format_args args) noexcept
{
char msg[1024];
vsnprintf(msg, sizeof(msg), fmt, ap);
Log(level, domain, msg);
}
void
LogFormat(LogLevel level, const Domain &domain, const char *fmt, ...) noexcept
{
std::va_list ap;
va_start(ap, fmt);
LogFormatV(level, domain, fmt, ap);
va_end(ap);
}
void
FormatDebug(const Domain &domain, const char *fmt, ...) noexcept
{
std::va_list ap;
va_start(ap, fmt);
LogFormatV(LogLevel::DEBUG, domain, fmt, ap);
va_end(ap);
}
void
FormatInfo(const Domain &domain, const char *fmt, ...) noexcept
{
std::va_list ap;
va_start(ap, fmt);
LogFormatV(LogLevel::INFO, domain, fmt, ap);
va_end(ap);
}
void
FormatNotice(const Domain &domain, const char *fmt, ...) noexcept
{
std::va_list ap;
va_start(ap, fmt);
LogFormatV(LogLevel::NOTICE, domain, fmt, ap);
va_end(ap);
}
void
FormatWarning(const Domain &domain, const char *fmt, ...) noexcept
{
std::va_list ap;
va_start(ap, fmt);
LogFormatV(LogLevel::WARNING, domain, fmt, ap);
va_end(ap);
}
void
FormatError(const Domain &domain, const char *fmt, ...) noexcept
{
std::va_list ap;
va_start(ap, fmt);
LogFormatV(LogLevel::ERROR, domain, fmt, ap);
va_end(ap);
}
void
Log(LogLevel level, const std::exception &e) noexcept
{
Log(level, exception_domain, GetFullMessage(e).c_str());
}
void
Log(LogLevel level, const std::exception &e, const char *msg) noexcept
{
LogFormat(level, exception_domain, "%s: %s", msg, GetFullMessage(e).c_str());
}
void
LogFormat(LogLevel level, const std::exception &e, const char *fmt, ...) noexcept
{
char msg[1024];
std::va_list ap;
va_start(ap, fmt);
vsnprintf(msg, sizeof(msg), fmt, ap);
va_end(ap);
Log(level, e, msg);
fmt::memory_buffer buffer;
#if FMT_VERSION >= 80000
fmt::vformat_to(std::back_inserter(buffer), format_str, args);
#else
fmt::vformat_to(buffer, format_str, args);
#endif
Log(level, domain, {buffer.data(), buffer.size()});
}
void
Log(LogLevel level, const std::exception_ptr &ep) noexcept
{
Log(level, exception_domain, GetFullMessage(ep).c_str());
Log(level, exception_domain, GetFullMessage(ep));
}
void
Log(LogLevel level, const std::exception_ptr &ep, const char *msg) noexcept
{
LogFormat(level, exception_domain, "%s: %s", msg,
GetFullMessage(ep).c_str());
}
void
LogFormat(LogLevel level, const std::exception_ptr &ep, const char *fmt, ...) noexcept
{
char msg[1024];
std::va_list ap;
va_start(ap, fmt);
vsnprintf(msg, sizeof(msg), fmt, ap);
va_end(ap);
Log(level, ep, msg);
}
void
LogErrno(const Domain &domain, int e, const char *msg) noexcept
{
LogFormat(LogLevel::ERROR, domain, "%s: %s", msg, strerror(e));
}
void
LogErrno(const Domain &domain, const char *msg) noexcept
{
LogErrno(domain, errno, msg);
}
static void
FormatErrnoV(const Domain &domain, int e, const char *fmt, std::va_list ap) noexcept
{
char msg[1024];
vsnprintf(msg, sizeof(msg), fmt, ap);
LogErrno(domain, e, msg);
}
void
FormatErrno(const Domain &domain, int e, const char *fmt, ...) noexcept
{
std::va_list ap;
va_start(ap, fmt);
FormatErrnoV(domain, e, fmt, ap);
va_end(ap);
}
void
FormatErrno(const Domain &domain, const char *fmt, ...) noexcept
{
const int e = errno;
std::va_list ap;
va_start(ap, fmt);
FormatErrnoV(domain, e, fmt, ap);
va_end(ap);
LogFmt(level, exception_domain, "{}: {}", msg, ep);
}

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -21,29 +21,80 @@
#define MPD_LOG_HXX
#include "LogLevel.hxx"
#include "util/Compiler.h"
#include <fmt/core.h>
#if FMT_VERSION < 70000 || FMT_VERSION >= 80000
#include <fmt/format.h>
#endif
#include <exception>
#include <string_view>
#include <utility>
class Domain;
void
Log(LogLevel level, const Domain &domain, const char *msg) noexcept;
gcc_printf(3,4)
void
LogFormat(LogLevel level, const Domain &domain, const char *fmt, ...) noexcept;
Log(LogLevel level, const Domain &domain, std::string_view msg) noexcept;
void
Log(LogLevel level, const std::exception &e) noexcept;
LogVFmt(LogLevel level, const Domain &domain,
fmt::string_view format_str, fmt::format_args args) noexcept;
template<typename S, typename... Args>
void
Log(LogLevel level, const std::exception &e, const char *msg) noexcept;
LogFmt(LogLevel level, const Domain &domain,
const S &format_str, Args&&... args) noexcept
{
#if FMT_VERSION >= 70000
return LogVFmt(level, domain, fmt::to_string_view(format_str),
fmt::make_args_checked<Args...>(format_str,
args...));
#else
/* expensive fallback for older libfmt versions */
const auto result = fmt::format(format_str, args...);
return Log(level, domain, result);
#endif
}
gcc_printf(3,4)
template<typename S, typename... Args>
void
LogFormat(LogLevel level, const std::exception &e,
const char *fmt, ...) noexcept;
FmtDebug(const Domain &domain,
const S &format_str, Args&&... args) noexcept
{
LogFmt(LogLevel::DEBUG, domain, format_str, args...);
}
template<typename S, typename... Args>
void
FmtInfo(const Domain &domain,
const S &format_str, Args&&... args) noexcept
{
LogFmt(LogLevel::INFO, domain, format_str, args...);
}
template<typename S, typename... Args>
void
FmtNotice(const Domain &domain,
const S &format_str, Args&&... args) noexcept
{
LogFmt(LogLevel::NOTICE, domain, format_str, args...);
}
template<typename S, typename... Args>
void
FmtWarning(const Domain &domain,
const S &format_str, Args&&... args) noexcept
{
LogFmt(LogLevel::WARNING, domain, format_str, args...);
}
template<typename S, typename... Args>
void
FmtError(const Domain &domain,
const S &format_str, Args&&... args) noexcept
{
LogFmt(LogLevel::ERROR, domain, format_str, args...);
}
void
Log(LogLevel level, const std::exception_ptr &ep) noexcept;
@@ -51,76 +102,36 @@ Log(LogLevel level, const std::exception_ptr &ep) noexcept;
void
Log(LogLevel level, const std::exception_ptr &ep, const char *msg) noexcept;
gcc_printf(3,4)
void
LogFormat(LogLevel level, const std::exception_ptr &ep,
const char *fmt, ...) noexcept;
static inline void
LogDebug(const Domain &domain, const char *msg) noexcept
{
Log(LogLevel::DEBUG, domain, msg);
}
gcc_printf(2,3)
void
FormatDebug(const Domain &domain, const char *fmt, ...) noexcept;
static inline void
LogInfo(const Domain &domain, const char *msg) noexcept
{
Log(LogLevel::INFO, domain, msg);
}
gcc_printf(2,3)
void
FormatInfo(const Domain &domain, const char *fmt, ...) noexcept;
static inline void
LogNotice(const Domain &domain, const char *msg) noexcept
{
Log(LogLevel::NOTICE, domain, msg);
}
gcc_printf(2,3)
void
FormatNotice(const Domain &domain, const char *fmt, ...) noexcept;
static inline void
LogWarning(const Domain &domain, const char *msg) noexcept
{
Log(LogLevel::WARNING, domain, msg);
}
gcc_printf(2,3)
void
FormatWarning(const Domain &domain, const char *fmt, ...) noexcept;
static inline void
LogError(const Domain &domain, const char *msg) noexcept
{
Log(LogLevel::ERROR, domain, msg);
}
inline void
LogError(const std::exception &e) noexcept
{
Log(LogLevel::ERROR, e);
}
inline void
LogError(const std::exception &e, const char *msg) noexcept
{
Log(LogLevel::ERROR, e, msg);
}
template<typename... Args>
inline void
FormatError(const std::exception &e, const char *fmt, Args&&... args) noexcept
{
LogFormat(LogLevel::ERROR, e, fmt, std::forward<Args>(args)...);
}
inline void
LogError(const std::exception_ptr &ep) noexcept
{
@@ -133,30 +144,4 @@ LogError(const std::exception_ptr &ep, const char *msg) noexcept
Log(LogLevel::ERROR, ep, msg);
}
template<typename... Args>
inline void
FormatError(const std::exception_ptr &ep,
const char *fmt, Args&&... args) noexcept
{
LogFormat(LogLevel::ERROR, ep, fmt, std::forward<Args>(args)...);
}
gcc_printf(2,3)
void
FormatError(const Domain &domain, const char *fmt, ...) noexcept;
void
LogErrno(const Domain &domain, int e, const char *msg) noexcept;
void
LogErrno(const Domain &domain, const char *msg) noexcept;
gcc_printf(3,4)
void
FormatErrno(const Domain &domain, int e, const char *fmt, ...) noexcept;
gcc_printf(2,3)
void
FormatErrno(const Domain &domain, const char *fmt, ...) noexcept;
#endif /* LOG_H */

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -103,10 +103,9 @@ log_date() noexcept
* characters.
*/
static int
chomp_length(const char *p) noexcept
chomp_length(std::string_view p) noexcept
{
size_t length = strlen(p);
return StripRight(p, length);
return StripRight(p.data(), p.size());
}
#ifdef HAVE_SYSLOG
@@ -137,11 +136,11 @@ ToSysLogLevel(LogLevel log_level) noexcept
}
static void
SysLog(const Domain &domain, LogLevel log_level, const char *message) noexcept
SysLog(const Domain &domain, LogLevel log_level, std::string_view message) noexcept
{
syslog(ToSysLogLevel(log_level), "%s: %.*s",
domain.GetName(),
chomp_length(message), message);
chomp_length(message), message.data());
}
void
@@ -161,12 +160,12 @@ LogFinishSysLog() noexcept
#endif
static void
FileLog(const Domain &domain, const char *message) noexcept
FileLog(const Domain &domain, std::string_view message) noexcept
{
fprintf(stderr, "%s%s: %.*s\n",
enable_timestamp ? log_date() : "",
domain.GetName(),
chomp_length(message), message);
chomp_length(message), message.data());
#ifdef _WIN32
/* force-flush the log file, because setvbuf() does not seem
@@ -178,14 +177,20 @@ FileLog(const Domain &domain, const char *message) noexcept
#endif /* !ANDROID */
void
Log(LogLevel level, const Domain &domain, const char *msg) noexcept
Log(LogLevel level, const Domain &domain, std::string_view msg) noexcept
{
#ifdef ANDROID
__android_log_print(ToAndroidLogLevel(level), "MPD",
"%s: %s", domain.GetName(), msg);
if (logListener != nullptr)
"%s: %.*s", domain.GetName(),
(int)msg.size(), msg.data());
if (logListener != nullptr) {
char buffer[1024];
snprintf(buffer, sizeof(buffer), "%s: %.*s",
domain.GetName(), (int)msg.size(), msg.data());
logListener->OnLog(Java::GetEnv(), ToAndroidLogLevel(level),
"%s: %s", domain.GetName(), msg);
buffer);
}
#else
if (level < log_threshold)

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -234,22 +234,22 @@ cycle_log_files() noexcept
if (out_path.IsNull())
return 0;
FormatDebug(log_domain, "Cycling log files");
LogDebug(log_domain, "Cycling log files");
close_log_files();
fd = open_log_file();
if (fd < 0) {
const std::string out_path_utf8 = out_path.ToUTF8();
FormatError(log_domain,
"error re-opening log file: %s",
out_path_utf8.c_str());
FmtError(log_domain,
"error re-opening log file: {}",
out_path_utf8);
return -1;
}
redirect_logs(fd);
close(fd);
FormatDebug(log_domain, "Done cycling log files");
LogDebug(log_domain, "Done cycling log files");
return 0;
#endif
}

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -40,10 +40,11 @@
#include "input/cache/Config.hxx"
#include "input/cache/Manager.hxx"
#include "event/Loop.hxx"
#include "event/Call.hxx"
#include "fs/AllocatedPath.hxx"
#include "fs/Config.hxx"
#include "playlist/PlaylistRegistry.hxx"
#include "zeroconf/ZeroconfGlue.hxx"
#include "zeroconf/Glue.hxx"
#include "decoder/DecoderList.hxx"
#include "pcm/AudioParser.hxx"
#include "pcm/Convert.hxx"
@@ -111,7 +112,7 @@
#include <climits>
#ifdef HAVE_CLOCALE
#ifndef ANDROID
#include <clocale>
#endif
@@ -157,7 +158,17 @@ glue_daemonize_init(const struct options *options,
static void
glue_mapper_init(const ConfigData &config)
{
mapper_init(config.GetPath(ConfigOption::PLAYLIST_DIR));
auto playlist_directory = config.GetPath(ConfigOption::PLAYLIST_DIR);
#ifdef ANDROID
/* if there is no explicit configuration, store playlists in
"/sdcard/Android/data/org.musicpd/files/playlists" */
if (playlist_directory.IsNull())
playlist_directory = context->GetExternalFilesDir(Java::GetEnv(),
"playlists");
#endif
mapper_init(std::move(playlist_directory));
}
#ifdef ENABLE_DATABASE
@@ -286,9 +297,8 @@ initialize_decoder_and_player(Instance &instance,
"positive integer", s);
if (result < MIN_BUFFER_SIZE) {
FormatWarning(config_domain, "buffer size %lu is too small, using %lu bytes instead",
(unsigned long)result,
(unsigned long)MIN_BUFFER_SIZE);
FmtWarning(config_domain, "buffer size {} is too small, using {} bytes instead",
result, MIN_BUFFER_SIZE);
result = MIN_BUFFER_SIZE;
}
@@ -334,7 +344,7 @@ Instance::BeginShutdownUpdate() noexcept
{
#ifdef ENABLE_DATABASE
#ifdef ENABLE_INOTIFY
mpd_inotify_finish();
inotify_update.reset();
#endif
if (update != nullptr)
@@ -358,11 +368,9 @@ MainConfigured(const struct options &options, const ConfigData &raw_config)
#endif
#ifndef ANDROID
#ifdef HAVE_CLOCALE
/* initialize locale */
std::setlocale(LC_CTYPE,"");
std::setlocale(LC_COLLATE, "");
#endif
#endif
const ScopeIcuInit icu_init;
@@ -443,7 +451,8 @@ MainConfigured(const struct options &options, const ConfigData &raw_config)
command_init();
for (auto &partition : instance.partitions) {
partition.outputs.Configure(instance.rtio_thread.GetEventLoop(),
partition.outputs.Configure(instance.io_thread.GetEventLoop(),
instance.rtio_thread.GetEventLoop(),
raw_config,
config.replay_gain);
partition.UpdateEffectiveReplayGainMode();
@@ -478,7 +487,27 @@ MainConfigured(const struct options &options, const ConfigData &raw_config)
};
#endif
ZeroconfInit(raw_config, instance.event_loop);
#ifdef HAVE_ZEROCONF
std::unique_ptr<ZeroconfHelper> zeroconf;
try {
auto &event_loop = instance.io_thread.GetEventLoop();
BlockingCall(event_loop, [&](){
zeroconf = ZeroconfInit(raw_config, event_loop);
});
} catch (...) {
LogError(std::current_exception(),
"Zeroconf initialization failed");
}
AtScopeExit(&zeroconf, &instance) {
if (zeroconf) {
auto &event_loop = instance.io_thread.GetEventLoop();
BlockingCall(event_loop, [&](){
zeroconf.reset();
});
}
};
#endif
#ifdef ENABLE_DATABASE
if (create_db) {
@@ -494,15 +523,21 @@ MainConfigured(const struct options &options, const ConfigData &raw_config)
if (raw_config.GetBool(ConfigOption::AUTO_UPDATE, false)) {
#ifdef ENABLE_INOTIFY
if (instance.storage != nullptr &&
instance.update != nullptr)
mpd_inotify_init(instance.event_loop,
*instance.storage,
*instance.update,
raw_config.GetUnsigned(ConfigOption::AUTO_UPDATE_DEPTH,
INT_MAX));
instance.update != nullptr) {
try {
instance.inotify_update =
mpd_inotify_init(instance.event_loop,
*instance.storage,
*instance.update,
raw_config.GetUnsigned(ConfigOption::AUTO_UPDATE_DEPTH,
INT_MAX));
} catch (...) {
LogError(std::current_exception());
}
}
#else
FormatWarning(config_domain,
"inotify: auto_update was disabled. enable during compilation phase");
LogWarning(config_domain,
"inotify: auto_update was disabled. enable during compilation phase");
#endif
}
#endif
@@ -535,10 +570,10 @@ MainConfigured(const struct options &options, const ConfigData &raw_config)
/* cleanup */
if (instance.state_file)
instance.state_file->Write();
instance.BeginShutdownUpdate();
ZeroconfDeinit();
instance.BeginShutdownPartitions();
}
@@ -593,6 +628,15 @@ Java_org_musicpd_Bridge_shutdown(JNIEnv *, jclass)
global_instance->Break();
}
gcc_visibility_default
JNIEXPORT void JNICALL
Java_org_musicpd_Bridge_pause(JNIEnv *, jclass)
{
if (global_instance != nullptr)
for (auto &partition : global_instance->partitions)
partition.pc.LockSetPause(true);
}
#else
static inline void
@@ -606,27 +650,26 @@ MainOrThrow(int argc, char *argv[])
MainConfigured(options, raw_config);
}
int mpd_main(int argc, char *argv[]) noexcept
int
mpd_main(int argc, char *argv[])
{
AtScopeExit() { log_deinit(); };
try {
MainOrThrow(argc, argv);
return EXIT_SUCCESS;
} catch (...) {
LogError(std::current_exception());
return EXIT_FAILURE;
}
MainOrThrow(argc, argv);
return EXIT_SUCCESS;
}
int
main(int argc, char *argv[]) noexcept
{
try {
AtScopeExit() { log_deinit(); };
#ifdef _WIN32
return win32_main(argc, argv);
#else
return mpd_main(argc, argv);
#endif
} catch (...) {
LogError(std::current_exception());
return EXIT_FAILURE;
}
#endif

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -40,7 +40,7 @@ extern Instance *global_instance;
* after doing some initialization.
*/
int
mpd_main(int argc, char *argv[]) noexcept;
mpd_main(int argc, char *argv[]);
#endif

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -24,7 +24,6 @@
#ifndef MPD_MAPPER_HXX
#define MPD_MAPPER_HXX
#include "util/Compiler.h"
#include "config.h"
#include <string>
@@ -44,7 +43,7 @@ mapper_init(AllocatedPath &&playlist_dir);
* is basically done by converting the URI to the file system charset
* and prepending the music directory.
*/
gcc_pure
[[gnu::pure]]
AllocatedPath
map_uri_fs(const char *uri) noexcept;
@@ -56,7 +55,7 @@ map_uri_fs(const char *uri) noexcept;
* @return the relative path in UTF-8, or an empty string if mapping
* failed
*/
gcc_pure
[[gnu::pure]]
std::string
map_fs_to_utf8(Path path_fs) noexcept;
@@ -65,7 +64,7 @@ map_fs_to_utf8(Path path_fs) noexcept;
/**
* Returns the playlist directory.
*/
gcc_const
[[gnu::const]]
const AllocatedPath &
map_spl_path() noexcept;
@@ -75,7 +74,7 @@ map_spl_path() noexcept;
*
* @return the path in file system encoding, or nullptr if mapping failed
*/
gcc_pure
[[gnu::pure]]
AllocatedPath
map_spl_utf8_to_fs(const char *name) noexcept;

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -20,8 +20,6 @@
#ifndef MPD_MIX_RAMP_INFO_HXX
#define MPD_MIX_RAMP_INFO_HXX
#include "util/Compiler.h"
#include <string>
class MixRampInfo {
@@ -35,17 +33,17 @@ public:
end.clear();
}
gcc_pure
[[gnu::pure]]
bool IsDefined() const noexcept {
return !start.empty() || !end.empty();
}
gcc_pure
[[gnu::pure]]
const char *GetStart() const noexcept {
return start.empty() ? nullptr : start.c_str();
}
gcc_pure
[[gnu::pure]]
const char *GetEnd() const noexcept {
return end.empty() ? nullptr : end.c_str();
}

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -63,7 +63,7 @@ public:
* is the same value which was passed to the constructor
* music_buffer_new().
*/
gcc_pure
[[gnu::pure]]
unsigned GetSize() const noexcept {
return buffer.GetCapacity();
}

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -105,7 +105,7 @@ struct MusicChunkInfo {
* Checks if the audio format if the chunk is equal to the
* specified audio_format.
*/
gcc_pure
[[gnu::pure]]
bool CheckFormat(AudioFormat audio_format) const noexcept;
#endif
};

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -22,7 +22,6 @@
#include "MusicChunkPtr.hxx"
#include "thread/Mutex.hxx"
#include "util/Compiler.h"
#ifndef NDEBUG
#include "pcm/AudioFormat.hxx"
@@ -59,7 +58,7 @@ public:
* Checks if the audio format if the chunk is equal to the specified
* audio_format.
*/
gcc_pure
[[gnu::pure]]
bool CheckFormat(AudioFormat other) const noexcept {
return !audio_format.IsDefined() ||
audio_format == other;
@@ -68,7 +67,7 @@ public:
/**
* Checks if the specified chunk is enqueued in the music pipe.
*/
gcc_pure
[[gnu::pure]]
bool Contains(const MusicChunk *chunk) const noexcept;
#endif
@@ -76,7 +75,7 @@ public:
* Returns the first #MusicChunk from the pipe. Returns
* nullptr if the pipe is empty.
*/
gcc_pure
[[gnu::pure]]
const MusicChunk *Peek() const noexcept {
const std::lock_guard<Mutex> protect(mutex);
return head.get();
@@ -100,13 +99,13 @@ public:
/**
* Returns the number of chunks currently in this pipe.
*/
gcc_pure
[[gnu::pure]]
unsigned GetSize() const noexcept {
const std::lock_guard<Mutex> protect(mutex);
return size;
}
gcc_pure
[[gnu::pure]]
bool IsEmpty() const noexcept {
return GetSize() == 0;
}

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -21,6 +21,7 @@
#include "Partition.hxx"
#include "Instance.hxx"
#include "Log.hxx"
#include "lib/fmt/ExceptionFormatter.hxx"
#include "song/DetachedSong.hxx"
#include "mixer/Volume.hxx"
#include "IdleFlags.hxx"
@@ -67,13 +68,14 @@ PrefetchSong(InputCacheManager &cache, const char *uri) noexcept
if (cache.Contains(uri))
return;
FormatDebug(cache_domain, "Prefetch '%s'", uri);
FmtDebug(cache_domain, "Prefetch '{}'", uri);
try {
cache.Prefetch(uri);
} catch (...) {
FormatError(std::current_exception(),
"Prefetch '%s' failed", uri);
FmtError(cache_domain,
"Prefetch '{}' failed: {}",
uri, std::current_exception());
}
}

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -27,6 +27,7 @@
#include "mixer/Listener.hxx"
#include "player/Control.hxx"
#include "player/Listener.hxx"
#include "protocol/RangeArg.hxx"
#include "ReplayGainMode.hxx"
#include "SingleMode.hxx"
#include "Chrono.hxx"
@@ -38,6 +39,7 @@
#include <memory>
struct Instance;
struct RangeArg;
class MultipleOutputs;
class SongLoader;
class ClientListener;
@@ -133,24 +135,20 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
* @param start the position of the first song to delete
* @param end the position after the last song to delete
*/
void DeleteRange(unsigned start, unsigned end) {
playlist.DeleteRange(pc, start, end);
void DeleteRange(RangeArg range) {
playlist.DeleteRange(pc, range);
}
void StaleSong(const char *uri) noexcept {
playlist.StaleSong(pc, uri);
}
void Shuffle(unsigned start, unsigned end) noexcept {
playlist.Shuffle(pc, start, end);
void Shuffle(RangeArg range) {
playlist.Shuffle(pc, range);
}
void MoveRange(unsigned start, unsigned end, int to) {
playlist.MoveRange(pc, start, end, to);
}
void MoveId(unsigned id, int to) {
playlist.MoveId(pc, id, to);
void MoveRange(RangeArg range, unsigned to) {
playlist.MoveRange(pc, range, to);
}
void SwapPositions(unsigned song1, unsigned song2) {
@@ -161,10 +159,8 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
playlist.SwapIds(pc, id1, id2);
}
void SetPriorityRange(unsigned start_position, unsigned end_position,
uint8_t priority) {
playlist.SetPriorityRange(pc, start_position, end_position,
priority);
void SetPriorityRange(RangeArg position_range, uint8_t priority) {
playlist.SetPriorityRange(pc, position_range, priority);
}
void SetPriorityId(unsigned song_id, uint8_t priority) {

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -22,6 +22,9 @@
#include "config/Param.hxx"
#include "config/Data.hxx"
#include "config/Option.hxx"
#include "net/AddressInfo.hxx"
#include "net/Resolver.hxx"
#include "net/ToString.hxx"
#include "util/IterableSplitString.hxx"
#include "util/RuntimeError.hxx"
#include "util/StringView.hxx"
@@ -41,6 +44,7 @@ static constexpr struct {
} permission_names[] = {
{ "read", PERMISSION_READ },
{ "add", PERMISSION_ADD },
{ "player", PERMISSION_PLAYER },
{ "control", PERMISSION_CONTROL },
{ "admin", PERMISSION_ADMIN },
{ nullptr, 0 },
@@ -54,6 +58,10 @@ static unsigned permission_default;
static unsigned local_permissions;
#endif
#ifdef HAVE_TCP
static std::map<std::string, unsigned> host_passwords;
#endif
static unsigned
ParsePermission(StringView s)
{
@@ -65,16 +73,20 @@ ParsePermission(StringView s)
int(s.size), s.data);
}
static unsigned parsePermissions(const char *string)
static unsigned
parsePermissions(std::string_view string)
{
assert(string != nullptr);
unsigned permission = 0;
for (const auto i : IterableSplitString(string, PERMISSION_SEPARATOR))
if (!i.empty())
permission |= ParsePermission(i);
/* for backwards compatiblity with MPD 0.22 and older,
"control" implies "play" */
if (permission & PERMISSION_CONTROL)
permission |= PERMISSION_PLAYER;
return permission;
}
@@ -82,6 +94,7 @@ void
initPermissions(const ConfigData &config)
{
permission_default = PERMISSION_READ | PERMISSION_ADD |
PERMISSION_PLAYER |
PERMISSION_CONTROL | PERMISSION_ADMIN;
for (const auto &param : config.GetParamList(ConfigOption::PASSWORD)) {
@@ -98,8 +111,7 @@ initPermissions(const ConfigData &config)
std::string password(value, separator);
unsigned permission = parsePermissions(separator + 1);
permission_passwords.insert(std::make_pair(std::move(password),
permission));
permission_passwords.emplace(std::move(password), permission);
});
}
@@ -115,17 +127,48 @@ initPermissions(const ConfigData &config)
: permission_default;
});
#endif
#ifdef HAVE_TCP
for (const auto &param : config.GetParamList(ConfigOption::HOST_PERMISSIONS)) {
permission_default = 0;
param.With([](StringView value){
auto [host_sv, permissions_s] = value.Split(' ');
unsigned permissions = parsePermissions(permissions_s);
const std::string host_s{host_sv};
for (const auto &i : Resolve(host_s.c_str(), 0,
AI_PASSIVE, SOCK_STREAM))
host_passwords.emplace(HostToString(i),
permissions);
});
}
#endif
}
#ifdef HAVE_TCP
int
getPermissionFromPassword(const char *password, unsigned *permission) noexcept
GetPermissionsFromAddress(SocketAddress address) noexcept
{
if (auto i = host_passwords.find(HostToString(address));
i != host_passwords.end())
return i->second;
return -1;
}
#endif
std::optional<unsigned>
GetPermissionFromPassword(const char *password) noexcept
{
auto i = permission_passwords.find(password);
if (i == permission_passwords.end())
return -1;
return std::nullopt;
*permission = i->second;
return 0;
return i->second;
}
unsigned

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -22,25 +22,42 @@
#include "config.h"
#include <optional>
struct ConfigData;
class SocketAddress;
static constexpr unsigned PERMISSION_NONE = 0;
static constexpr unsigned PERMISSION_READ = 1;
static constexpr unsigned PERMISSION_ADD = 2;
static constexpr unsigned PERMISSION_CONTROL = 4;
static constexpr unsigned PERMISSION_ADMIN = 8;
static constexpr unsigned PERMISSION_PLAYER = 16;
int
getPermissionFromPassword(const char *password, unsigned *permission) noexcept;
/**
* @return the permissions for the given password or std::nullopt if
* the password is not accepted
*/
[[gnu::pure]]
std::optional<unsigned>
GetPermissionFromPassword(const char *password) noexcept;
[[gnu::const]]
unsigned
getDefaultPermissions() noexcept;
#ifdef HAVE_UN
[[gnu::const]]
unsigned
GetLocalPermissions() noexcept;
#endif
#ifdef HAVE_TCP
[[gnu::pure]]
int
GetPermissionsFromAddress(SocketAddress address) noexcept;
#endif
void
initPermissions(const ConfigData &config);

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -22,6 +22,7 @@
#include "PlaylistError.hxx"
#include "queue/Playlist.hxx"
#include "queue/QueuePrint.hxx"
#include "protocol/RangeArg.hxx"
#define SONG_FILE "file: "
#define SONG_TIME "Time: "
@@ -35,20 +36,17 @@ playlist_print_uris(Response &r, const playlist &playlist)
}
void
playlist_print_info(Response &r, const playlist &playlist,
unsigned start, unsigned end)
playlist_print_info(Response &r, const playlist &playlist, RangeArg range)
{
const Queue &queue = playlist.queue;
if (end > queue.GetLength())
/* correct the "end" offset */
end = queue.GetLength();
if (start > end)
/* an invalid "start" offset is fatal */
if (!range.CheckClip(queue.GetLength()))
throw PlaylistError::BadRange();
queue_print_info(r, queue, start, end);
if (range.IsEmpty())
return;
queue_print_info(r, queue, range.start, range.end);
}
void
@@ -62,7 +60,7 @@ playlist_print_id(Response &r, const playlist &playlist,
/* no such song */
throw PlaylistError::NoSuchSong();
playlist_print_info(r, playlist, position, position + 1);
playlist_print_info(r, playlist, {unsigned(position), position + 1U});
}
bool
@@ -87,18 +85,24 @@ playlist_print_find(Response &r, const playlist &playlist,
void
playlist_print_changes_info(Response &r, const playlist &playlist,
uint32_t version,
unsigned start, unsigned end)
RangeArg range)
{
queue_print_changes_info(r, playlist.queue, version,
start, end);
const Queue &queue = playlist.queue;
range.ClipRelaxed(queue.GetLength());
queue_print_changes_info(r, queue, version,
range.start, range.end);
}
void
playlist_print_changes_position(Response &r,
const playlist &playlist,
uint32_t version,
unsigned start, unsigned end)
RangeArg range)
{
const Queue &queue = playlist.queue;
range.ClipRelaxed(queue.GetLength());
queue_print_changes_position(r, playlist.queue, version,
start, end);
range.start, range.end);
}

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -23,6 +23,7 @@
#include <cstdint>
struct playlist;
struct RangeArg;
class SongFilter;
class Response;
@@ -41,8 +42,7 @@ playlist_print_uris(Response &r, const playlist &playlist);
* Throws #PlaylistError if the range is invalid.
*/
void
playlist_print_info(Response &r, const playlist &playlist,
unsigned start, unsigned end);
playlist_print_info(Response &r, const playlist &playlist, RangeArg range);
/**
* Sends the song with the specified id to the client.
@@ -73,7 +73,7 @@ playlist_print_find(Response &r, const playlist &playlist,
void
playlist_print_changes_info(Response &r, const playlist &playlist,
uint32_t version,
unsigned start, unsigned end);
RangeArg range);
/**
* Print changes since the specified playlist version, position only.
@@ -82,6 +82,6 @@ void
playlist_print_changes_position(Response &r,
const playlist &playlist,
uint32_t version,
unsigned start, unsigned end);
RangeArg range);
#endif

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -19,10 +19,14 @@
#include "RemoteTagCache.hxx"
#include "RemoteTagCacheHandler.hxx"
#include "lib/fmt/ExceptionFormatter.hxx"
#include "input/ScanTags.hxx"
#include "util/DeleteDisposer.hxx"
#include "util/Domain.hxx"
#include "Log.hxx"
static constexpr Domain remote_tag_cache_domain("remote_tag_cache");
RemoteTagCache::RemoteTagCache(EventLoop &event_loop,
RemoteTagCacheHandler &_handler) noexcept
:handler(_handler),
@@ -42,9 +46,9 @@ RemoteTagCache::Lookup(const std::string &uri) noexcept
std::unique_lock<Mutex> lock(mutex);
KeyMap::insert_commit_data hint;
auto result = map.insert_check(uri, Item::Hash(), Item::Equal(), hint);
if (result.second) {
auto *item = new Item(*this, uri);
auto [tag, value] = map.insert_check(uri, Item::Hash(), Item::Equal(), hint);
if (value) {
auto item = new Item(*this, uri);
map.insert_commit(*item, hint);
waiting_list.push_back(*item);
lock.unlock();
@@ -60,9 +64,9 @@ RemoteTagCache::Lookup(const std::string &uri) noexcept
item->scanner->Start();
} catch (...) {
FormatError(std::current_exception(),
"Failed to scan tags of '%s'",
uri.c_str());
FmtError(remote_tag_cache_domain,
"Failed to scan tags of '{}': {}",
uri, std::current_exception());
item->scanner.reset();
@@ -70,15 +74,13 @@ RemoteTagCache::Lookup(const std::string &uri) noexcept
ItemResolved(*item);
return;
}
} else if (result.first->scanner) {
} else if (tag->scanner) {
/* already scanning this one - no-op */
} else {
/* already finished: re-invoke the handler */
auto &item = *result.first;
idle_list.erase(waiting_list.iterator_to(item));
invoke_list.push_back(item);
idle_list.erase(waiting_list.iterator_to(*tag));
invoke_list.push_back(*tag);
ScheduleInvokeHandlers();
}
@@ -130,7 +132,8 @@ RemoteTagCache::Item::OnRemoteTag(Tag &&_tag) noexcept
void
RemoteTagCache::Item::OnRemoteTagError(std::exception_ptr e) noexcept
{
FormatError(e, "Failed to scan tags of '%s'", uri.c_str());
FmtError(remote_tag_cache_domain,
"Failed to scan tags of '{}': {}", uri, e);
scanner.reset();

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -22,7 +22,7 @@
#include "input/RemoteTagScanner.hxx"
#include "tag/Tag.hxx"
#include "event/DeferEvent.hxx"
#include "event/InjectEvent.hxx"
#include "thread/Mutex.hxx"
#include <boost/intrusive/list.hpp>
@@ -40,7 +40,7 @@ class RemoteTagCache final {
RemoteTagCacheHandler &handler;
DeferEvent defer_invoke_handler;
InjectEvent defer_invoke_handler;
Mutex mutex;
@@ -68,20 +68,20 @@ class RemoteTagCache final {
struct Hash : std::hash<std::string> {
using std::hash<std::string>::operator();
gcc_pure
[[gnu::pure]]
std::size_t operator()(const Item &item) const noexcept {
return std::hash<std::string>::operator()(item.uri);
}
};
struct Equal {
gcc_pure
[[gnu::pure]]
bool operator()(const Item &a,
const Item &b) const noexcept {
return a.uri == b.uri;
}
gcc_pure
[[gnu::pure]]
bool operator()(const std::string &a,
const Item &b) const noexcept {
return a == b.uri;

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2020 The Music Player Daemon Project
* Copyright 2003-2021 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

Some files were not shown because too many files have changed in this diff Show More