Compare commits

...

2620 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 #1224 #1225
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 #1023
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: #1124
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 (#3)
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 #994 - 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
Max Kellermann
56fa7368e8 release v0.22 2020-09-23 15:26:51 +02:00
Max Kellermann
e9df4116fd db/upnp: store UPnPDirContent in local variable
Fixes use-after-free because the temporary goes out of scope.
2020-09-23 15:25:39 +02:00
Max Kellermann
5492304254 meson.build: drop obsolete warning flag -Wno-noexcept-type
We don't support GCC 7 anymore.
2020-09-23 15:13:19 +02:00
Max Kellermann
416d4e4433 NEWS: update recommended compilers 2020-09-23 15:12:17 +02:00
Max Kellermann
eae2863286 doc/user.rst: add GitHub link 2020-09-23 15:11:00 +02:00
Max Kellermann
39bc196f64 doc/user.rst: move download link to downloads page 2020-09-23 15:07:50 +02:00
Max Kellermann
157dfa320f doc: improve manpage markup 2020-09-23 15:04:22 +02:00
Max Kellermann
9b4f2ac79b doc/meson.build: kludge to fix manpage installation directory
Ugly workaround for https://github.com/mesonbuild/meson/issues/1550
2020-09-23 14:47:43 +02:00
Max Kellermann
c843bce9f5 LogLevel: rename DEFAULT to NOTICE
"DEFAULT" is a bad name - all it says is that it's the default value,
but it doesn't say what it means.  The name NOTICE mimics the syslog
level.
2020-09-23 14:22:33 +02:00
Max Kellermann
e3106a019d LogInit: provide mappings for LogLevel::{ERROR,WARNING} 2020-09-23 14:17:11 +02:00
Max Kellermann
3e0ceb12d5 LogInit: rename "secure" to "info"
Calling this "secure" never made sense.  Messages about client
connects are just a small part of what gets logged as "secure",
a.k.a. "info".
2020-09-23 14:15:58 +02:00
Max Kellermann
050adf6640 doc: rewrite the log_level documentation 2020-09-23 14:14:54 +02:00
Max Kellermann
60bbc9f626 LogInit: use StringIsEqual() 2020-09-23 13:28:19 +02:00
Max Kellermann
065926d6a4 decoder/ffmpeg: support album art
Closes https://github.com/MusicPlayerDaemon/MPD/issues/892
2020-09-23 12:50:28 +02:00
Max Kellermann
85bab67083 input/uring: safe cancellation
My concept with `class CancellableOperation` doesn't work properly,
because the kernel may continue to write to the given buffer as soon
as the read finishes.

To fix this, this commit adds `class ReadOperation` which owns the
buffer and the `struct iovec`.  Instances of this class persist until
the read really finishes, even if the operation is canceled.
2020-09-23 11:07:26 +02:00
Max Kellermann
4001379663 io/uring/Operation: add method ReplaceUring() 2020-09-22 21:50:48 +02:00
Max Kellermann
382273abc5 io/uring/Operation: add API documentation 2020-09-22 21:49:48 +02:00
Max Kellermann
85af4d6916 meson.build: add -Wdouble-promotion 2020-09-22 20:40:53 +02:00
Max Kellermann
6825e1144e net/SocketError: work around -Wvla by defining a constexpr variable 2020-09-22 20:40:53 +02:00
Max Kellermann
45f8449c72 doc/user.rst: change C++14 to C++17 2020-09-22 20:40:49 +02:00
Max Kellermann
71bf1a8a3d doc/protocol.rst: improve "pause" documentation
And un-deprecate "pause" without parameter (toggles pause).  I have no
idea why it was deprecated long ago; the deprecation notice was copied
from the ancient MPD wiki.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/944
2020-09-22 20:16:02 +02:00
Max Kellermann
bc47a16943 Merge tag 'v0.21.26' into master
release v0.21.26
2020-09-21 15:20:02 +02:00
Max Kellermann
566787f041 release v0.21.26 2020-09-21 15:14:43 +02:00
Max Kellermann
79b2366387 archive/iso9660: fix odd seeking bug (assertion failure)
Skip the beginning of a sector if the last seek was odd, and clear the
buffer on seek.
2020-09-21 15:11:21 +02:00
Max Kellermann
5acea014b0 archive/iso9660: remove unused macro CEILING() 2020-09-21 15:11:17 +02:00
Max Kellermann
5130acf3ea decoder/ffmpeg: implement protocols() and uri_decode() (for RTSP)
This implements the feature that was missing/broken in this bug
report: https://github.com/MusicPlayerDaemon/MPD/issues/930
2020-09-21 14:57:12 +02:00
Max Kellermann
a22d1c88d7 decoder/ffmpeg: pass InputStream by pointer
Prepare for an implementation without InputStream.
2020-09-21 14:53:18 +02:00
Max Kellermann
85849c9396 decoder/plugin: add method protocols()
Similar to commit 4e2a551f30 but for
decoder plugins.  This is tailored for the FFmpeg decoder plugin which
implements some protocols (e.g. RTSP) as demuxer plugin.
2020-09-21 14:53:18 +02:00
Max Kellermann
d3c257d97d CommandLine: reindent lambdas 2020-09-21 14:52:45 +02:00
Max Kellermann
c13fe63f10 archive/iso9660: fix odd seeking bug (assertion failure)
Skip the beginning of a sector if the last seek was odd, and clear the
buffer on seek.
2020-09-21 14:43:58 +02:00
Max Kellermann
07842abcb0 input/ffmpeg: add "hls+http://" to the list of supported protocols
Same as e10b867fe6 but it got lost in
the merge, because the v0.22 branch uses a different way to detect
supported protocols at runtime.
2020-09-21 12:55:32 +02:00
Max Kellermann
07e524509f input/Plugin: add noexcept 2020-09-21 11:43:18 +02:00
Max Kellermann
2c05752071 archive/iso9660: remove unused function CEILING() 2020-09-21 11:38:24 +02:00
Max Kellermann
7c8427b0f7 Merge branch 'v0.21.x' into master 2020-09-21 11:37:50 +02:00
Max Kellermann
b72801abf3 util/ByteOrder: add FromLE16S() 2020-09-21 11:15:45 +02:00
Desuwa
23d5a2b862 Support opus header gain tags and match opus playback volume to other tracks when ReplayGain is enabled. 2020-09-21 10:51:06 +02:00
Rosen Penev
7715311117 fix double promotions
Found with -Wdouble-promotion

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-09-21 09:13:51 +02:00
Max Kellermann
7552f70c8d Merge branch 'gcc5' of git://github.com/neheb/MPD into master 2020-09-21 09:07:19 +02:00
Max Kellermann
0acc398c52 Merge branch 'v0.21.x' into master 2020-09-17 14:44:20 +02:00
Max Kellermann
4c1cfca95b db/update/InotifyUpdate: pass path by value to recursive_watch_subdirectories() 2020-09-17 14:18:29 +02:00
Max Kellermann
e113ce9621 db/update/InotifyUpdate: obey .mpdignore files
Closes https://github.com/MusicPlayerDaemon/MPD/issues/846
2020-09-17 14:17:17 +02:00
Rosen Penev
821d08999a remove GCC5 hacks
GCC5 cannot build mpd.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-09-16 18:10:27 -07:00
Max Kellermann
e8213220e2 db/update/InotifyUpdate: split the WatchDirectory constructor 2020-09-16 21:08:22 +02:00
Max Kellermann
83f9d2a963 db/update/InotifyUpdate: use class DirectoryReader 2020-09-16 21:02:07 +02:00
Max Kellermann
bf97ebf89f db/update/InotifyUpdate: convert pointer to reference 2020-09-16 20:59:41 +02:00
Max Kellermann
5b22d27cbb db/update/InotifyUpdate: remove commented log call 2020-09-16 20:59:40 +02:00
Max Kellermann
e907ff43ae command/file, storage/{nfs,smbclient}: use PathTraitsFS::IsSpecialFilename()
Eliminate some duplicate code.
2020-09-16 20:57:46 +02:00
Max Kellermann
b18fc3a8d0 db/update/InotifySource: use auto 2020-09-16 20:40:27 +02:00
Max Kellermann
a8e23c4140 db/update/InotifySource: add noexcept 2020-09-16 20:40:06 +02:00
Max Kellermann
fc3861b421 db/update/InotifyQueue: add noexcept 2020-09-16 20:40:03 +02:00
Max Kellermann
e81bb5d8f1 db/update/Inotify*: include cleanup 2020-09-16 20:39:44 +02:00
Max Kellermann
32f4f15831 player/Thread: call OnPlayerSync() in SeekDecoder()
This fixes a spurious "single" mode bug which occurs when using "play"
or "seek" to start playback on the song that is currently paused: in
that case, the main thread never queues the next song, and at the end
of the song, the player thread exits Run(), stopping playback, and
after that, the main thread starts the next song without considering
"single" mode.

By calling OnPlayerSync(), we ensure that the main thread gets a
chance to queue the next song before the player thread exits the Run()
loop.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/850
2020-09-16 20:36:19 +02:00
Max Kellermann
e29c06b718 player/Thread: add another code comment explaining OnPlayerSync() 2020-09-16 20:12:52 +02:00
Max Kellermann
d9d511f33e player/Thread: update function name in comment 2020-09-16 20:12:05 +02:00
Max Kellermann
c61a3b8d13 LogBackend: change the initial log_threshold to DEFAULT
The log levels have always been very confusing (and badly named), but
this was most confusing: if there's a log level called "default", why
is it not the default?

Closes https://github.com/MusicPlayerDaemon/MPD/issues/926
2020-09-16 17:17:34 +02:00
Max Kellermann
e10b867fe6 decoder/ffmpeg: add "hls+http://" to the list of supported protocols 2020-09-16 16:36:07 +02:00
Max Kellermann
43e230f543 decoder/ffmpeg: remove "rtsp://" from the list of supported protocols
FFmpeg implements RTSP as a demuxer, not as a protocol handler.  Thus,
avio_open() cannot be used, and our input plugin cannot handle RTSP.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/930
2020-09-16 16:32:31 +02:00
Max Kellermann
e8380cf2aa Merge branch 'v0.21.x' into master 2020-09-07 21:15:53 +02:00
Max Kellermann
b2ae5298a7 archive/iso9660: implement seeking 2020-09-07 21:13:28 +02:00
Max Kellermann
17dd21ac7f archive/iso9660: fix unaligned reads
Oh the horror!  This plugin cannot possibly ever have worked.  It was
broken from the start, when it was added in commit 37796699cf nearly
twelve (!) years ago.

The plugin would always read at sector boundaries, so it could only
ever work at multiples of 2 kB.
2020-09-07 21:08:46 +02:00
Max Kellermann
1a5e0ef7c9 test/test_archive_iso9660.sh: use an odd chunk size to trigger bug
This makes the unit test fail.  D'oh!
2020-09-07 20:53:46 +02:00
Max Kellermann
979a7a1dcc test/run_input: add option --chunk-size 2020-09-07 20:52:37 +02:00
Max Kellermann
291be84704 Merge branch 'v0.21.x' into master 2020-09-07 20:18:40 +02:00
Max Kellermann
962cf32ba7 test/run_input: pass FileDescriptor to dump_input_stream() 2020-09-07 20:14:39 +02:00
Max Kellermann
ae23682372 system/FileDescriptor: add method FullWrite() 2020-09-07 20:13:43 +02:00
Max Kellermann
540919f256 *: use nullptr instead of NULL 2020-09-07 20:08:27 +02:00
Max Kellermann
398281cd76 io/FileDescriptor: add method FullRead() 2020-09-07 20:07:47 +02:00
Max Kellermann
88446ccde9 test/run_filter: use Filter::Flush() 2020-09-07 20:07:40 +02:00
Max Kellermann
6238cc0734 test/run_filter: pass ConstBuffer<void> to FullWrite() 2020-09-07 20:07:33 +02:00
Max Kellermann
fd4823c507 test/run_filter: fix error message 2020-09-07 20:07:29 +02:00
Max Kellermann
68bcfd8bf0 test/run_filter: check for partial writes 2020-09-07 20:07:24 +02:00
Max Kellermann
1d332746af test/run_filter: move code to WriteOrThrow() 2020-09-07 20:07:18 +02:00
Max Kellermann
f3e133c617 test/run_filter: use class FileDescriptor 2020-09-07 20:07:13 +02:00
Max Kellermann
1678a6eb59 test/run_filter: ensure that partial frames will not get passed to the filter 2020-09-07 20:07:08 +02:00
Max Kellermann
b4dc2c07d5 test/run_filter: move the buffer into the loop 2020-09-07 20:07:03 +02:00
Max Kellermann
d7838950d8 test/run_input: use WithBufferedOutputStream() 2020-09-07 20:04:13 +02:00
Max Kellermann
2e93a83dd5 test/run_input: convert pointer to reference 2020-09-07 20:02:12 +02:00
Max Kellermann
67c7116f05 Merge branch 'v0.21.x' into master 2020-09-04 18:35:21 +02:00
bitkeeper
9aa432c078 Support soxr custom recipes.
MPD uses soxr with prefined resample recipes. Soxr also support defining a recipe your self.
This commit will support a custom recipe by changing the existing quality setting to "custom".

The same structs as the predefined recipes uses can now set by hand.

This will make the following settings available:
- precision 16|20|24|28|32 bits, example "28"
- phase_response - 0-100, example "45"
- passband_end - used bandwidth of source 80-99.7%, example "99.7.0"
- stopband_begin - anti aliasing 100.0+%, example "100".
- attenuation - signal reduciton in dB's, 0-30. example "3.0".
- flags "0" - additional bitmask with extra settings

The data is set in the structs soxr_quality_spec and soxr_io_spec (found in soxr.h).
2020-09-04 18:32:03 +02:00
Max Kellermann
db8b419b8c archive/iso9660: free iso9660_stat_t as early as possible 2020-09-04 18:17:24 +02:00
Max Kellermann
990f631cbc archive/bzip2: make variables more local 2020-09-04 18:02:22 +02:00
Max Kellermann
db46d84458 archive/bzip2: move the eof check out of the ScopeUnlock 2020-09-04 18:01:29 +02:00
Max Kellermann
9e6c4f8d80 archive/bzip2: throw on unexpected input EOF
Don't silently return 0 when there is no more data, because this may
crash the caller.  And flush output even if input EOF has been reached.
2020-09-04 17:54:53 +02:00
Max Kellermann
41b47f95c5 archive/bzip2: simplify bz_stream initializer 2020-09-04 17:52:04 +02:00
Max Kellermann
15939fd87c archive/bzip2: fold Open() into constructor 2020-09-04 17:51:41 +02:00
Max Kellermann
f63c343f68 archive/bzip2: reorder fields to improve packing 2020-09-04 17:51:22 +02:00
Max Kellermann
1a516e7744 archive/bzip2: add override 2020-09-04 17:51:21 +02:00
Max Kellermann
5c9d97775f python/build/libs.py: update Boost to 1.74.0 2020-09-04 14:49:11 +02:00
Max Kellermann
64aadcd13f python/build/libs.py: update CURL to 7.72.0 2020-09-04 14:48:40 +02:00
Max Kellermann
1f6a7d6462 archive/zzip: fix crash on corrupt ZIP file
Sometimes, zzip_file_read() returns 0 even though the end of the file
was not reached.  This causes assertion failures in
DecoderBridge::Read().

Closes https://github.com/MusicPlayerDaemon/MPD/issues/935
2020-09-04 14:34:54 +02:00
Max Kellermann
e44b953d9a archive/zzip: use zzip_ssize_t to avoid integer overflows 2020-09-04 14:33:44 +02:00
Max Kellermann
6c85020630 archive/zzip: add override 2020-09-04 14:33:44 +02:00
Max Kellermann
9d910320f3 archive/zzip: pass std::shared_ptr as template parameter
This eliminates a tiny amount of overhead because the compiler can
choose how to pass the parameter.
2020-09-04 14:33:44 +02:00
Max Kellermann
c53074efc9 archive/zzip: add explicit 2020-09-04 14:33:11 +02:00
Max Kellermann
3b51c53eca win32/build.py: add -D_FORTIFY_SOURCE=0
This fixes the Windows build.  Linking failed because some packages
(e.g. libFLAC) default to enabling `_FORTIFY_SOURCE`, which is broken
in recent mingw versions
(https://github.com/msys2/MINGW-packages/issues/5803).
2020-09-04 14:33:11 +02:00
Max Kellermann
0aa0ffb67b decoder/sndfile: allow partial reads at end of file
While libsndfile doesn't like partial reads in the middle of a file
(see commit 95ac6071b9), it allows partial reads at the end of a file.
It doesn't pay attention to the file size when issuing a read.

Commit ecb67a1ed1 (MPD 0.18.12) was a regression: previously,
partial reads at the end of a file were possible, but switching to
decoder_read_full() made this an error condition.  This way, a portion
at the end of each file was lost, leading to corruption with gapless
playback (https://github.com/MusicPlayerDaemon/MPD/issues/936).

This fix switches to the newly introduced function
decoder_read_much(), which does the same as the code before commit
ecb67a1ed1.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/936
2020-09-04 13:35:00 +02:00
Max Kellermann
33f70931dd decoder/API: add decoder_read_much() 2020-09-04 13:35:00 +02:00
Max Kellermann
8830ea319f decoder/API: add noexcept 2020-09-04 13:35:00 +02:00
Johann Uhrmann
38498d3ee2 Removed duplicate check for negative song time 2020-08-23 12:17:10 +02:00
Max Kellermann
35d1d0bc6e Merge branch 'document-no-config-option' of git://github.com/naglis/MPD 2020-08-21 14:36:04 +02:00
Naglis Jonaitis
fefdb7d96d doc/mpd.1.rst: document --no-config option 2020-08-21 15:22:07 +03:00
Max Kellermann
1d39a35b05 Merge branch 'use-stderr-option-in-docs' of git://github.com/naglis/MPD 2020-08-21 13:59:43 +02:00
Naglis Jonaitis
902f18fcca doc/user.rst: use --stderr option in examples
--stdout was renamed to --stderr in 7261739526.
2020-08-21 14:49:06 +03:00
Naglis Jonaitis
8145f34248 doc/mpd.1.rst: fix typo 2020-08-21 14:41:48 +03:00
Max Kellermann
ddb524b6b2 input/uring: add noexcept 2020-08-14 16:45:00 +02:00
Max Kellermann
cbcdc73f9a system/ByteOrder: add noexcept 2020-08-14 16:36:24 +02:00
Max Kellermann
4f6c54ecb3 output/osx: catch kAudioDevicePropertyHogMode errors
Our AudioObjectGetPropertyDataT() wrapper throws exception on error,
and calling it from OSXOutput::Disable() can cause MPD crash due to
std::terminate().

Closes https://github.com/MusicPlayerDaemon/MPD/issues/932
2020-08-14 16:33:43 +02:00
Max Kellermann
2bdf1b2284 test/meson.build: add explicit dependency from run_output on libevent.a
We could exclude that feature if neither ALSA nor httpd are enabled,
but that's too complicated for this small debug program.
2020-08-14 14:40:39 +02:00
Max Kellermann
3f0805e7f6 doc/meson.build: let custom_target() install manpages
install_man() is currently broken with Meson and doesn't support a
custom target argument.

The problem with this kludge is that both mpd.1 and mpd.conf.5 are
installed in /usr/share/man/man1/, but apparently, there's no solution
yet.
2020-08-14 13:50:49 +02:00
Max Kellermann
4c93165a67 doc/meson.build: use install_man() 2020-08-14 13:18:52 +02:00
kaliko
5f63ffd86c Convert raw manpages to reStructured text
Build with `rst2man mpd.1.rst mpd.1`
2020-08-14 13:14:34 +02:00
Max Kellermann
9df2469e51 meson_options.txt: add option html_manual 2020-08-14 13:02:19 +02:00
Max Kellermann
2e73e605f7 doc/meson.build: convert option "documentation" to Meson "feature"
This allows automatic optional detection of Sphinx.  This will be
useful when we start building the manpages with Sphinx, which many
users may want to have.
2020-08-14 13:02:08 +02:00
Max Kellermann
2bcd8516ea Merge branch 'use-ref-for-ffmpeg-decoder' of git://github.com/naglis/MPD 2020-08-14 13:01:37 +02:00
Naglis Jonaitis
5c3301f9a3 doc/plugins.rst: use reference to ffmpeg plugin section
Currently, the hardcoded URL points to a non-existent page.
2020-08-14 13:51:04 +03:00
Naglis Jonaitis
f1487c30bf doc/plugins.rst: document archive plugins 2020-08-14 13:38:31 +03:00
Naglis Jonaitis
08c70b0702 doc/user.rst: document include_optional directive 2020-08-08 16:30:27 +03:00
Max Kellermann
df1bf28caa Merge branch 'document-libmpg123-limitations' of git://github.com/naglis/MPD 2020-08-06 20:04:30 +02:00
Naglis Jonaitis
8b67ae0460 doc/plugins.rst: document libmpg123 limitations 2020-08-01 15:04:11 +03:00
Max Kellermann
dbdf782e59 net/{Resolver,HostParser}: include <cstring>
Fixup after e4dad42ca1
2020-07-23 17:40:29 +02:00
Max Kellermann
f102cbb613 net/AllocatedSocketAddress: add missing forward declaration 2020-07-23 17:40:29 +02:00
Max Kellermann
5522967286 net/StaticSocketAddress: add IWYU pragma 2020-07-23 17:40:29 +02:00
Max Kellermann
a2f42e6424 time/ISO8601: use <cstdlib> 2020-07-23 16:26:18 +02:00
Max Kellermann
bdfe6c2c45 lib/dbus/Values: use using instead of typedef 2020-07-23 16:26:18 +02:00
Max Kellermann
5e1a2e2a93 lib/dbus/Values: add uint32_t and uint64_t support 2020-07-23 16:26:18 +02:00
Max Kellermann
7376f31c97 lib/dbus/Message: add noexcept 2020-07-23 16:26:18 +02:00
Max Kellermann
155fc8fa5a include cleanup 2020-07-23 16:26:18 +02:00
Max Kellermann
7daf80a0c0 util/RuntimeError: add IWYU pragma 2020-07-23 16:10:28 +02:00
Max Kellermann
eb87c28225 util/CharUtil: fix doc typo 2020-07-23 16:08:52 +02:00
Rosen Penev
c876d6a51c lib/icu: fix build without libc iconv support
Need to check for it in iconv.h. Otherwise meson prefixes a __builtin variant in the check.
2020-07-23 14:09:43 +02:00
Max Kellermann
47f54b5650 input/smbclient: close handle on stat error 2020-07-20 22:43:49 +02:00
Max Kellermann
fbfa1723e7 lib/smbclient/Mutex: remove obsolete library 2020-07-20 22:40:27 +02:00
Max Kellermann
a74140842c storage/smbclient: add Mutex attribute
This per-object Mutex replaces the global `smbclient_mutex`.
2020-07-20 22:39:59 +02:00
Max Kellermann
f5a85a816c storage/smbclient: store SmbclientStorage reference 2020-07-20 22:37:11 +02:00
Max Kellermann
2a15fafbd7 input/smbclient: remove mutex locking
This is no longer necessary with the new API.
2020-07-20 22:34:56 +02:00
Max Kellermann
2fc4802886 neighbor/smbclient: remove mutex locking
This is no longer necessary with the new API.
2020-07-20 22:32:59 +02:00
Max Kellermann
bb3f487ee5 lib/smbclient/Context: add global Mutex for smbc_{new,free}_context()
Preparing to replace `smbclient_mutex`, for finer-grained locking.
2020-07-20 22:32:00 +02:00
Max Kellermann
7d97d0ae87 lib/smbclient/Init: move code to SmbclientContext::New()
We no longer need to call smbc_init() because we don't need the compat
layer anymore.
2020-07-20 22:23:18 +02:00
Max Kellermann
f6dc9bcad6 */smbclient: use the new API with SMBCCTX parameter
As a side effect, the input plugin closes the SMB/CIFS connection
after closing the file.

This solves one part of
https://github.com/MusicPlayerDaemon/MPD/issues/916
2020-07-20 22:05:05 +02:00
Max Kellermann
697531a948 lib/smbclient/Context: new wrapper for SMBCCTX 2020-07-20 22:01:10 +02:00
Max Kellermann
3c745b4bc6 neighbor/smbclient: remove obsolete commented code 2020-07-20 18:13:38 +02:00
Max Kellermann
3a08a6ad72 doc/plugins.rst: document sample formats for OpenSLES 2020-07-20 15:27:41 +02:00
Max Kellermann
448b397cb8 output/sles: support floating point samples
According to https://developer.android.com/ndk/guides/audio/opensl/android-extensions

This feature was mentioned in https://github.com/MusicPlayerDaemon/MPD/issues/922
2020-07-20 15:23:50 +02:00
Max Kellermann
64a1386eb6 output/sles: move SampleFormat selection to switch/case block 2020-07-20 14:47:36 +02:00
Max Kellermann
77c2efe171 python/build/libs.py: update CURL to 7.71.1 2020-07-20 12:37:54 +02:00
Max Kellermann
587c0f6232 python/build/libs.py: update FFmpeg to 4.3.1 2020-07-20 12:37:16 +02:00
Max Kellermann
64e8abf203 python/build/libs.py: update libvorbis to 1.3.7 2020-07-20 12:34:16 +02:00
Max Kellermann
6c40d2a656 python/build/libs.py: update libmpdclient to 2.19 2020-07-20 12:32:19 +02:00
Max Kellermann
cf674e9273 input/Init: downgrade PluginUnconfigured to LogLevel::DEBUG
`LogLevel::INFO` is logged by default, but this message shall only
appear with `--verbose`.

This finally solves https://github.com/MusicPlayerDaemon/MPD/issues/430
2020-07-16 13:19:14 +02:00
Max Kellermann
9bda0379af increment version number to 0.21.26 2020-07-16 12:53:22 +02:00
Naglis Jonaitis
b04c6fbd72 doc: fix a few typos and missing words 2020-07-10 19:01:53 +03:00
Max Kellermann
b74a91427d Merge tag 'v0.21.25'
release v0.21.25
2020-07-06 21:47:30 +02:00
Max Kellermann
c67372f8af release v0.21.25 2020-07-06 21:41:53 +02:00
Max Kellermann
00789de7d4 db/upnp/Object: root nodes are allowed to omit parent_id and name
This fixes compatibility with Plex DLNA.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/851
2020-07-06 21:36:30 +02:00
Max Kellermann
9964a5ffe8 db/update/Service: avoid copying the mount point path 2020-07-06 21:09:58 +02:00
Max Kellermann
5ece9685c2 PluginUnavailable: backport class PluginUnconfigured from master
Stop bothering people about the Tidal/Qobuz plugins.
2020-07-06 21:08:22 +02:00
Max Kellermann
e7c5a42821 Log: add Log() and LogFormat() overloads with std::exception_ptr
Make LogError()/FormatError() wrappers for those.  Now we can log
exceptions with a lower level.
2020-07-06 21:08:04 +02:00
Max Kellermann
36e6079c57 Log: make LogLevel the first parameter
Prepare for templated functions.
2020-07-06 21:07:26 +02:00
Max Kellermann
e5f23678ca Log: use GetFullMessage() to print exceptions
Print all nested exceptions on a single line to avoid confusion.
2020-07-06 21:07:16 +02:00
Max Kellermann
c3cfb5fe16 Merge branch 'v0.21.x' 2020-07-06 20:56:52 +02:00
Max Kellermann
749ad7cd83 PluginUnavailable: inherit the base class constructor 2020-07-06 20:40:25 +02:00
Max Kellermann
0b59f4eaee doc/plugins.rst: merge redundant nfs:// documentation 2020-07-06 20:37:58 +02:00
Max Kellermann
402663de74 doc/plugins.rst: more markup 2020-07-06 20:34:04 +02:00
Max Kellermann
eaa66c7ee3 doc/plugins.rst: add smb:// with password example
Closes https://github.com/MusicPlayerDaemon/MPD/issues/864
2020-07-06 20:32:41 +02:00
Max Kellermann
996714d6ff doc/plugins.rst: more markup 2020-07-06 20:32:11 +02:00
Max Kellermann
fe48e5596f command/storage: automatically scan new mounts
Closes https://github.com/MusicPlayerDaemon/MPD/issues/841
2020-07-06 20:23:41 +02:00
Max Kellermann
d7744d2b8e command/storage: check if storage is already mounted
Mounting one storage URI twice on different mount points can lead to
conflicts with the database cache file, and it doesn't make a lot of
sense.

But most importantly, our udisks storage plugin will unmount the disk
from the kernel VFS, and if two exist, they will compete with each
others.  We could (and should) fix this in the udisks storage plugin,
but for now, this workaround is good enough (and useful).
2020-07-06 18:02:47 +02:00
Max Kellermann
33ee35ab92 command/storage: check if mount point is busy
When mounting something over a directory that is already a mount
point, CompositeStorage::Mount() silently overwrites the previously
mounted storage, disposing it.  After that, SimpleDatabase::Mount()
will fail and handle_mount() will roll back the
CompositeStorage::Mount() command, effectively unmounting what was
there before (and also leaking memory).

Closes https://github.com/MusicPlayerDaemon/MPD/issues/918
2020-07-06 17:49:38 +02:00
Max Kellermann
5b291ff768 db/update/Walk: pass concatenated .mpdignore URI to storage.MapUTF8()
Fixes the "Unrecognized URI" error with the udisks storage plugin,
which is caused by the kludge in UdisksStorage::MapUTF8().
2020-07-06 17:19:38 +02:00
Max Kellermann
39d6816a6d neighbor/upnp: roll back changes if DoOpen() fails 2020-07-06 16:23:58 +02:00
Max Kellermann
6517b2d2ac neighbor/upnp: remove D-Bus filter and match in Close()
Fixes use-after-free crash bug during MPD shutdown.
2020-07-06 16:15:18 +02:00
Max Kellermann
bfdf13dca3 decoder/Plugin: allow scan_{file,stream}() to throw
Bug #915 is about an I/O exception thrown where none was allowed,
leading to crash via std::terminate().  However, instead of catching
and logging the error inside the decoder plugin, it should be able to
propagate the I/O error to the MPD core, so MPD can avoid trying other
decoder plugins.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/915
2020-07-06 14:13:34 +02:00
Max Kellermann
86823af685 Merge branch 'v0.21.x' 2020-07-02 15:34:16 +02:00
Max Kellermann
daefc61aa4 output/osx: postpone start until the end of Play()
Wait until there is data in the ring buffer.
2020-07-02 15:26:38 +02:00
Max Kellermann
6fed6e50e4 output/osx: merge some duplicate code 2020-07-02 15:25:51 +02:00
Max Kellermann
bc9e074822 output/osx: postpone start until the first Play() call
Wait until there is some data; don't let our render callback be
invoked without any data.
2020-07-02 15:21:54 +02:00
Max Kellermann
8047102542 output/osx: don't restart AudioUnit at the end of Cancel()
We shouldn't restart the AudioUnit while the ring buffer is empty, or
else our render callback may emit noise.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/771
2020-07-02 15:20:43 +02:00
Max Kellermann
fe5b81e180 output/osx: check started in Close() and Cancel() 2020-07-02 15:19:40 +02:00
Max Kellermann
f032925c2d output/osx: add started flag
This will keep track of AudioOutputUnitStart() and
AudioOutputUnitStop().  This will provide some separation between "not
(yet) (re)started" and "paused".
2020-07-02 15:18:37 +02:00
Max Kellermann
8125a5dddb output/osx: don't uninitialize AudioUnit if restart fails
This shall be done by Close(), which will be called automatically
after an error.
2020-07-02 15:10:03 +02:00
Max Kellermann
154170e475 output/osx: clear pause flag only after successful AudioOutputUnitStart() 2020-07-02 15:08:59 +02:00
Max Kellermann
fb83936feb apple/AudioUnit: add AudioUnitSetPropertyT() 2020-07-02 14:59:40 +02:00
Max Kellermann
db8bf52f7d apple/AudioObject: add AudioObjectGetStringProperty() 2020-07-02 13:50:05 +02:00
Max Kellermann
756f0b8027 apple: build static library
Move build rules from src/output/plugins/meson.build
2020-07-02 13:49:54 +02:00
Max Kellermann
b1fba8d3d7 apple/AudioObject: add missing inline 2020-07-02 13:49:52 +02:00
Max Kellermann
4d88bddfe2 Merge branch 'v0.21.x' 2020-07-01 23:07:57 +02:00
Max Kellermann
e606044271 apple/AudioUnit: library wrapping AudioUnit*() functions 2020-07-01 23:02:22 +02:00
Max Kellermann
bcbb3371ff apple/AudioUnit: rename to AudioObject.hxx 2020-07-01 22:49:03 +02:00
Max Kellermann
de632882d1 output/osx: move code to FindAudioDeviceByName() 2020-07-01 22:48:12 +02:00
Max Kellermann
745e492d15 output/osx: use [[maybe_unused]] 2020-07-01 22:41:00 +02:00
Max Kellermann
c5dc615efe output/osx: use IsDigitASCII() 2020-07-01 22:39:54 +02:00
Max Kellermann
a08d4b3d66 Merge branch 'v0.21.x' 2020-07-01 22:09:33 +02:00
Max Kellermann
beeb02025e output/osx: use range-based for 2020-07-01 22:06:36 +02:00
Max Kellermann
cdf7062597 apple/AudioUnit: wrapper functions for AudioObject properties 2020-07-01 22:05:11 +02:00
Max Kellermann
346084da1e apple/Throw: new helper library replacing osx_os_status_to_cstring() 2020-07-01 22:05:11 +02:00
Max Kellermann
bbceb5eb91 output/osx: silently ignore some errors in osx_output_set_device() 2020-07-01 22:05:11 +02:00
Max Kellermann
90d85319c2 apple/ErrorRef: new library wrapping CFErrorRef 2020-07-01 22:05:10 +02:00
Max Kellermann
3d03683e7d output: use StringIsEqual() 2020-07-01 22:04:26 +02:00
Max Kellermann
d8a74802d1 apple/StringRef: new library wrapping CFStringRef 2020-07-01 22:01:53 +02:00
Max Kellermann
191919d1b1 output/osx: remove trailing newline from exception messages 2020-07-01 22:01:51 +02:00
Max Kellermann
df38e7565b util/HugeAllocator: import std::swap() 2020-07-01 21:56:58 +02:00
Max Kellermann
cb49a03fd7 util/HugeAllocator: add noexcept 2020-07-01 21:56:54 +02:00
Max Kellermann
faee5bbb78 decoder/opus: implement End Trimming (RFC7845 4.4)
Closes https://github.com/MusicPlayerDaemon/MPD/issues/867
2020-07-01 21:26:34 +02:00
Max Kellermann
7befab7e83 decoder/opus: keep track of the granulepos
Will be needed for End Trimming (RFC7845 4.4,
https://github.com/MusicPlayerDaemon/MPD/issues/867).
2020-07-01 21:21:06 +02:00
Max Kellermann
4244e61214 decoder/opus: simplify indentation in HandleAudio() 2020-07-01 21:19:52 +02:00
Max Kellermann
46eab05045 decoder/opus: allocate buffer only in the first chained song
Fixes memory leak.  That's what we get for
2020-07-01 21:07:49 +02:00
Max Kellermann
5ca137c73c decoder/opus: add API docs 2020-07-01 20:55:18 +02:00
Max Kellermann
760238fe16 decoder/opus: apply pre-skip (RFC7845 4.2)
Fixes the first part of
https://github.com/MusicPlayerDaemon/MPD/issues/867
2020-07-01 20:44:53 +02:00
Max Kellermann
a99b4abae8 decoder/OpusHead: return pre-skip 2020-07-01 17:51:07 +02:00
Max Kellermann
472881cb95 util/ByteOrder: remove redundant inline keywords from constexpr functions 2020-07-01 17:50:34 +02:00
Max Kellermann
c4efc37ad8 system/ByteOrder: move to util/ 2020-07-01 17:49:57 +02:00
Max Kellermann
691b6a236e output/osx: improve sample rate selection
The formula in osx_output_score_sample_rate() to detect multiples of
the source sample rate was broken: when given a 44.1 kHz input file,
it preferred 16 kHz over 48 kHz, because its `frac_portion(16)=0.75`
is smaller than `frac_portion(48)=0.91`.

That formula, introduced by commit 40a1ebee29, looks completely
wrong.  It doesn't do what the code comment pretends it does.

Instead of using that `frac_portion` to calculate a score, this patch
adds to the score only if `frac_portion` is nearly `0` or `1`.  This
means that the factor is nearly integer.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/904
2020-07-01 17:38:08 +02:00
Max Kellermann
c72697ea27 Merge branch 'v0.21.x' 2020-07-01 17:37:35 +02:00
Max Kellermann
5c7243d3ad output/osx: make several fields const 2020-07-01 17:35:39 +02:00
Max Kellermann
44cfdff39a output/osx: make variables more local 2020-07-01 17:35:33 +02:00
Max Kellermann
5eedda691a output/osx: make more AudioObjectPropertyAddress instances static constexpr 2020-07-01 17:35:19 +02:00
Max Kellermann
a30d5e1b6a output/osx: make AudioObjectPropertyAddress variables static constexpr 2020-07-01 17:34:12 +02:00
Max Kellermann
8ef09a0a71 output/osx: don't use C99 designated initializers
Fixes `-Wpedantic`.
2020-07-01 17:34:06 +02:00
Max Kellermann
e8044663b3 output/{alsa,osx}: use ConstBuffer::empty() 2020-07-01 17:32:37 +02:00
Max Kellermann
8444c33514 output/osx: don't use variable-length arrays 2020-07-01 17:31:46 +02:00
Max Kellermann
e709d9d15c Merge branch 'v0.21.x' 2020-07-01 17:29:39 +02:00
Max Kellermann
2b7328b434 output/osx: fix coding style 2020-07-01 17:11:02 +02:00
Max Kellermann
e0e5ed62ee meson.build: defaults for "build.c_std" and "build.cpp_std"
Since Meson 0.51, there are special build options for "native:true"
builds, prefixed with "build.".  This change breaks cross builds
because `GenParseName.cxx` is no longer built with `-std=c++17`.

This patch adds defaults for "build.c_std" and "build.cpp_std".

Closes https://github.com/MusicPlayerDaemon/MPD/issues/890
2020-07-01 17:04:48 +02:00
Max Kellermann
3d7147390f Merge branch 'v0.21.x' 2020-07-01 16:56:17 +02:00
Max Kellermann
ca705e1e37 python/build/meson.py: set BOOST_ROOT for Meson 0.54
Commit
08224dafcb
changed Meson to require BOOST_ROOT for cross builds.
2020-07-01 16:55:28 +02:00
Max Kellermann
3c5ef504f8 test/meson.build: add explicit dependency from run_output on libevent.a
We could exclude that feature if neither ALSA nor httpd are enabled,
but that's too complicated for this small debug program.
2020-07-01 15:26:02 +02:00
Max Kellermann
25b5ca6435 output/plugins/meson.build: add dependency on libevent.a for ALSA 2020-07-01 15:24:52 +02:00
Max Kellermann
fd217daad4 meson.build: always write encoder/Features.h
Fixes a build failure in `CommandLine.cxx`.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/905
2020-07-01 15:16:14 +02:00
Max Kellermann
d9f9b3df10 input/file: detect premature end of file
A bug report (https://github.com/MusicPlayerDaemon/MPD/issues/912)
suggests that on Linux, reading on `cifs` files may rarely return 0 (=
end of file) before the end of the file has really been reached.  But
that's just a theory which I need to validate, so this runtime check
shall catch this condition before the assertion in
DecoderBridge::Read() crashes MPD.  Let's see.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/912
2020-07-01 15:14:27 +02:00
Max Kellermann
a43ee97746 util/UriUtil: strip credentials from smb:// URIs
Closes https://github.com/MusicPlayerDaemon/MPD/issues/910
2020-06-22 22:48:56 +02:00
Max Kellermann
43c32372e7 util/UriUtil: make schemes array static 2020-06-22 22:48:07 +02:00
Max Kellermann
5716cde1fb queue/PlaylistEdit: fix crash in SetSongIdRange() while playing
An assertion failure in UpdateQueuedSong() could trigger because the
`prev` parameter is always `nullptr`, but `queued` may be set.  And in
fact, calling UpdateQueuedSong() is only necessary when the queued
song was edited, to re-queue it with the new range.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/901
2020-06-11 07:07:02 +02:00
Max Kellermann
b7a99b4a4b increment version number to 0.21.25 2020-06-11 06:29:08 +02:00
Max Kellermann
c6a7f6dabc Merge tag 'v0.21.24'
release v0.21.24
2020-06-10 22:58:41 +02:00
Max Kellermann
24741c5d06 release v0.21.24 2020-06-10 22:48:50 +02:00
Max Kellermann
6b3a282db4 lib/curl/Request: don't enable CURLOPT_NETRC on Windows
Our Windows build is built with `--disable-netrc`, and that makes
CURLOPT_NETRC fail, causing failures with all streams.  D'oh!

Closes https://github.com/MusicPlayerDaemon/MPD/issues/886
2020-06-10 22:46:42 +02:00
Max Kellermann
7583cfe9b7 {android,win32}/build.py: enable the GME decoder plugin
Closes https://github.com/MusicPlayerDaemon/MPD/issues/891
2020-06-10 21:33:29 +02:00
Max Kellermann
aafc9ce75b decoder/gme: use class NarrowPath() for Windows compatibility 2020-06-10 21:22:00 +02:00
Max Kellermann
fea326530b decoder/gme: simplify LoadGmeAndM3u() by moving code to ReplaceSuffix() 2020-06-10 21:20:49 +02:00
Max Kellermann
8925cc17d8 decoder/gme: use StringAfterPrefix() 2020-06-10 21:11:08 +02:00
Max Kellermann
14412c867f add a few IWYU pragmas 2020-06-10 21:10:33 +02:00
Max Kellermann
c5cc256bf2 decoder/gme: use Path::GetSuffix() 2020-06-10 21:02:07 +02:00
Max Kellermann
563c7318f9 fs/AllocatedPath: add method GetSuffix() 2020-06-10 21:00:41 +02:00
Max Kellermann
e92129f449 doc/protocol.rst: clarify the term "UNIX time"
Closes https://github.com/MusicPlayerDaemon/MPD/issues/893
2020-06-10 20:42:42 +02:00
Max Kellermann
96a273bf3b Merge branch 'misc/tar-python' of git://github.com/ibmibmibm/MPD 2020-06-10 17:54:22 +02:00
Max Kellermann
66c27d2c13 Merge branch 'document-idle-neighbor-mount' of git://github.com/naglis/MPD 2020-06-10 17:53:03 +02:00
Max Kellermann
374cc51f77 decoder/Bridge: add flag to make initial seek errors fatal
When the client wants to seek, but the decoder has already finished
decoding the current song, the player restarts the decoder with an
initial seek at the new position.  When this initial seek fails, MPD
pretends nothing has happened and plays this song from the start.

With this new flag, a restarted decoder marks the initial seek as
"essential" and fails the decoder if that seek fails.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/895
2020-06-10 17:49:10 +02:00
Max Kellermann
c031f9aa5d systemnd: configure LimitMEMLOCK for io_uring
The io_uring buffer is allocated as memlocked memory, as MPD needs to
be able to lock memory.
2020-06-09 21:09:00 +02:00
Max Kellermann
068006ebd7 decoder/Bridge: install an InputStreamHandler on local files
Before the advent of io_uring (commit dae8da7066), this didn't
matter, because the `FileInputStream` never called this.  But
`UringInputStream` is derived from `AsyncInputStream`, and needs the
handler to signal completion.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/898
2020-06-09 21:07:38 +02:00
Naglis Jonaitis
d2362b7c31 doc: document neighbor and mount idle subsystems 2020-06-07 16:43:04 +03:00
Shen-Ta Hsieh
9a4059ba39 misc: use python builtin tar library when /bin/tar not found 2020-06-05 11:22:52 +08:00
Max Kellermann
759f4231d2 meson.build: set default option default_library=static
For subprojects.
2020-06-04 18:44:47 +02:00
Max Kellermann
0cefb61a2e test/meson.build: install GTest from fallback Meson wrap 2020-06-04 14:56:43 +02:00
Max Kellermann
b7ab1a9d79 test/meson.build: disable GTest warning "ScopedTrace was marked unused but was used" 2020-06-04 10:32:02 +02:00
Shen-Ta Hsieh
d181ecce7b macos: change CI xcode to 10.3 for c++17 support
c++17 is offered by default with Xcode 10
https://developer.apple.com/documentation/xcode_release_notes/xcode_10_release_notes
2020-06-04 08:35:02 +08:00
Shen-Ta Hsieh
d2d53cc9d6 doc: add docs for wasapi plugin 2020-05-30 22:21:03 +08:00
Shen-Ta Hsieh
93d87854e9 src/output: add wasapi output and mixer plugin 2020-05-30 22:21:03 +08:00
Shen-Ta Hsieh
e5eac71d72 win32: add COM helper classes 2020-05-30 22:21:03 +08:00
Max Kellermann
f20b927858 Merge branch 'v0.21.x' 2020-05-30 14:05:18 +02:00
Rosen Penev
e4dad42ca1 use std chr functions
The ones in std have overloads for const char/char.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-05-30 13:36:53 +02:00
Max Kellermann
99afe8e6d1 lib/icu/Win32: paranoid-ify the buffer length checks
Passing `length+1` to `MultiByteToWideChar()` means the function may
fill the whole buffer with output data, and could theoretically
overwrite the null terminator.  In practice, this will never happen,
but this way, it's slightly more correct.

Also, null-terminate after `MultiByteToWideChar()`, after we got the
real output length.  Again, this would never have been a problem, but
who knows...
2020-05-30 13:29:09 +02:00
Rosen Penev
1008d5f67c use cwchar include
Needed for std::wmemchr under libcxx

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-05-30 13:22:04 +02:00
Shen-Ta Hsieh
169810e8f4 lib/icu: add null terminate in win32 string and wstring 2020-05-30 04:04:34 +08:00
Shen-Ta Hsieh
8e07ea7ad8 src/db: fitting libmpdclient interface 2020-05-29 19:00:16 +02:00
Max Kellermann
9f5c6d29b2 output/osx: use range-based for 2020-05-28 15:59:52 +02:00
Max Kellermann
f6823cc679 output/osx: move code to FindAudioDeviceByName() 2020-05-28 15:54:57 +02:00
Max Kellermann
69c0f0fe99 apple/AudioUnit: wrapper functions for AudioObject properties 2020-05-28 15:54:57 +02:00
Max Kellermann
28a00472ff apple/Throw: new helper library replacing osx_os_status_to_cstring() 2020-05-28 15:06:53 +02:00
Max Kellermann
8d540737b9 output/osx: silently ignore some errors in osx_output_set_device() 2020-05-28 15:06:51 +02:00
Max Kellermann
1112d779be apple/ErrorRef: new library wrapping CFErrorRef 2020-05-28 15:06:41 +02:00
Max Kellermann
ecced0ce13 apple/StringRef: new library wrapping CFStringRef 2020-05-28 15:06:38 +02:00
Max Kellermann
d751df0a73 storage/State: disable -Wcomma to work around Boost compiler warning 2020-05-28 14:00:31 +02:00
Max Kellermann
2c084781b0 output/openal: disable -Wdeprecated-declarations on Apple 2020-05-28 13:59:52 +02:00
Max Kellermann
6e1a21a42a output/osx: make several fields const 2020-05-28 13:59:32 +02:00
Max Kellermann
80e8338014 output/osx: make variables more local 2020-05-28 13:44:28 +02:00
Max Kellermann
bfaa7afcb0 output/osx: make more AudioObjectPropertyAddress instances static constexpr 2020-05-28 13:39:46 +02:00
Max Kellermann
ae7d550a01 meson.build: remove -Wall -Wextra, to be set by Meson 2020-05-28 13:19:34 +02:00
Max Kellermann
7fdbaa6156 output/osx: make AudioObjectPropertyAddress variables static constexpr 2020-05-27 19:50:44 +02:00
Max Kellermann
aa7dc62f72 output/osx: don't use C99 designated initializers
Fixes `-Wpedantic`.
2020-05-27 19:50:43 +02:00
Max Kellermann
6a4992118a lib/ffmpeg/Time: redefine AV_TIME_BASE_Q with initializer list
libavutil's macro definition is a compound literal, which is illegal
in C++.  Fixes yet another -Wpedantic warning.
2020-05-27 16:55:55 +02:00
Max Kellermann
f03cc1012d lib/upnp/Compat: workaround for -Wkeyword-macro 2020-05-27 16:50:27 +02:00
Max Kellermann
736a696f98 lib/upnp: drop support for libupnp versions older than 1.8 2020-05-27 16:49:02 +02:00
Max Kellermann
caec384ed0 archive/ArchiveList, input/Registry: avoid zero-sized array
Some more `-Wpedantic` fixups.
2020-05-27 16:31:52 +02:00
Max Kellermann
8fdc6dec44 meson.build: default to warning_level=3
Enables `-Wpedantic`.
2020-05-27 16:17:28 +02:00
Max Kellermann
5e93e882c9 Merge branch 'v0.21.x' 2020-05-27 16:16:30 +02:00
Max Kellermann
30d97fe8a0 meson.build: fix the WildMidi check when the feature is disabled
Fixes regression from commit 69f09648a4
2020-05-27 16:06:49 +02:00
Max Kellermann
5cb0080052 meson.build: default to warning_level=2
This branch isn't yet ready for level 3 (`-Wpedantic`) due to several
C++ violations (e.g. variable length arrays).  These are already
cleaned up in the master branch (0.22).
2020-05-27 15:57:13 +02:00
Max Kellermann
8e4ca23727 lib/ffmpeg/Time: replace C99 compound literal with C++ initializer list 2020-05-27 15:54:34 +02:00
Max Kellermann
bdc861f058 util/TemplateString: remove extra semicolon 2020-05-27 15:46:55 +02:00
Rosen Penev
8925040262 remove some more extra semicolons
Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-05-27 15:36:53 +02:00
Max Kellermann
c065950ced .travis.yml: disable zzip on OS X to fix Travis-CI build failure 2020-05-27 15:31:34 +02:00
Max Kellermann
257a77fa35 {android,win32}/build.py: build libmodplug and WildMidi
Closes https://github.com/MusicPlayerDaemon/MPD/issues/866
2020-05-27 15:03:49 +02:00
Max Kellermann
4e5d6e560b decoder/modplug: assume ModPlug is built as static library on Windows 2020-05-27 15:03:46 +02:00
Max Kellermann
d276d8eda2 decoder/wildmidi: assume WildMidi is built as static library on Windows 2020-05-27 15:03:35 +02:00
Max Kellermann
ebcb5e9368 decoder/wildmidi: use NarrowPath, fixing the Windows build 2020-05-27 15:03:33 +02:00
Max Kellermann
69f09648a4 meson.build: attempt to detect WildMidi using pkg-config
The WildMidi project added the pkg-config file in version 0.3.3, but
unfortunately, Debian still doesn't ship it 4 years later:

 https://bugs.debian.org/916631

However, for cross-compiling, the pkg-config file is very helpful.
2020-05-27 15:03:16 +02:00
Max Kellermann
9adda30c38 NEWS: move two lines below Windows/Android 2020-05-27 14:33:43 +02:00
Shen-Ta Hsieh
c5f80dc543 Add .clang-format 2020-05-27 18:58:55 +08:00
Max Kellermann
d2d4a0251e .gitignore: add emacs lsp-mode files 2020-05-26 21:07:56 +02:00
Max Kellermann
f7b6431b6f meson.build: work around Meson bug detecting strndup() on Windows
Work around Meson bug https://github.com/mesonbuild/meson/issues/3672
2020-05-26 20:50:56 +02:00
Max Kellermann
03b9bd3a9e python/build/libs.py: update FFmpeg to 4.2.3 2020-05-26 18:54:56 +02:00
Max Kellermann
6cc58ccb9b lib/icu/Converter: add missing <string_view> include 2020-05-26 17:48:01 +02:00
Max Kellermann
210c270624 test/test_pcm_export: eliminate zero-length arrays
C++ doesn't allow that.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/875
2020-05-26 16:50:40 +02:00
Max Kellermann
be94b4373a util/OffsetPointer: add noexcept 2020-05-14 15:44:23 +02:00
Max Kellermann
eeec0ee804 dsd/Dsd2Pcm: convert struct GenerateCtableValue to lambda
Since we have dropped support for GCC 6 a while ago, we can use
constexpr lambdas now.
2020-05-07 15:04:51 +02:00
Max Kellermann
a24ef280cc meson.build: require GCC 8 or clang 5
Commit 60f957ed64 broken the GCC 7 build, but instead of working
around missing C++17 features in old compilers, let's update the
compiler version requirements.

This commit raises the clang requirement to version 5 because this is
the first version to support `constexpr` lambdas, to be used to
`Dsd2Pcm.cxx`.
2020-05-07 15:04:50 +02:00
Max Kellermann
d1d6a3871e Merge branch 'v0.21.x' 2020-05-07 15:04:41 +02:00
Max Kellermann
61aed60f6d python/build/libs.py: update CURL to 7.70.0 2020-05-07 14:18:55 +02:00
Max Kellermann
2cc323c9fe python/build/libs.py: update Boost to 1.73.0 2020-05-07 14:18:21 +02:00
Max Kellermann
f24ab120ee android/build.py: use -fpic instead of -fPIC on ARM/Aarch64
Sync with the Android NDK build scripts.
2020-05-07 13:58:36 +02:00
Max Kellermann
68349bc55c android/build.py: use -mfpu=vfpv3-d16 on ARMv7
This flag is used by the Android NDK build scripts as well, and this
fixes a build failure (assembler error) with FFmpeg and NDK r21.
2020-05-07 13:50:33 +02:00
Max Kellermann
60f957ed64 util/MimeType: use string_view::substr()
Fixes regression from commit db93bb996c because
ParseMimeTypeParameters() assumed the items were null-terminated, but
after that commit, they were not anymore.
2020-05-06 20:33:13 +02:00
Max Kellermann
864d26cd1b Merge branch 'bind' of git://github.com/neheb/MPD 2020-05-06 06:14:55 +02:00
Max Kellermann
ba576ffa37 Merge branch 'v0.21.x' 2020-05-05 19:00:53 +02:00
Max Kellermann
209364adf2 db/simple: fix crash when mounting twice
The `db->close()` call was a `nullptr` dereference because the `db`
variable had already been moved.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/839
2020-05-05 18:57:29 +02:00
Max Kellermann
dae8da7066 input/uring: new input plugin using io_uring
This is the final piece of the series to establish io_uring support on
Linux.

MPD doesn't need io_uring for its efficient bulk I/O support, but to
allow file I/O to be cancelled.  This is a big problem on CIFS/NFS
mounts where processes sleep uninterruptable if the file server
disappears, deadlocking MPD.

With io_uring, a flaky NFS connection allows MPD to continue to work
(even though there are still deadlocks inside MPD which need to be
addressed).

This plugin does not yet use cancellable `open()` using
`IORING_OP_OPENAT`.  This will be implemented later.

Lots of other optimization opportunities for io_uring are still
missing as well - for example the database update could benefit a lot,
but unfortunately, io_uring doesn't have `readdir()` support just yet.
2020-05-05 17:41:03 +02:00
Max Kellermann
cdf8ac001c event/Loop: integrate io_uring support 2020-05-05 17:13:14 +02:00
Max Kellermann
62d0ceabcc io/uring: basic Linux io_uring support 2020-05-05 17:10:17 +02:00
Max Kellermann
935e622915 event/Loop: allow calling AddFD()... before starting the EventThread
Relax the assertions.  This is necessary if BlockingCall() is used
before the thread is started.
2020-05-05 17:10:17 +02:00
Max Kellermann
1efbbfcd6f GitVersion: make GIT_VERSION const 2020-05-05 15:12:40 +02:00
Max Kellermann
e0edf0b206 meson.build: move VERSION and others to Version.h 2020-05-05 15:12:11 +02:00
Max Kellermann
4e9fa36176 meson.build: remove unused macro PACKAGE_VERSION 2020-05-05 15:08:39 +02:00
Max Kellermann
8f178401e4 */plugins/meson.build: define feature macros in Features.h
This makes ccache more efficient when recompiling with different
plugins.
2020-05-05 15:06:50 +02:00
Max Kellermann
8c1d78873d system/KernelVersion: new library 2020-05-05 14:30:56 +02:00
Max Kellermann
9815d10137 system/FileDescriptor: move to io/ 2020-05-05 14:27:03 +02:00
Max Kellermann
97f7270aa8 fs/FileSystem: remove unused function FOpen() 2020-05-05 14:19:29 +02:00
Max Kellermann
1787aa5e00 decoder/sidplay: drop support for libsidplayfp < 1.8 2020-05-05 13:53:10 +02:00
Rosen Penev
e6a77e1297 remove std::bind usage as much as possible
Reduces unstripped size. stripped size is the same.

Also took the time to remove using std::placeholders.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-05-04 15:40:28 -07:00
skidoo23
e251fd0053 Add info about new song length format 2020-04-30 13:35:29 +02:00
Max Kellermann
24afdee35c command/all: "tagtypes" requires no permissions
The command is used to configure the client's connection, and this
shouldn't require any permissions.  The client should be able to do
that before sending a password.
2020-04-30 13:08:09 +02:00
Max Kellermann
7aea285361 Revert "Fix unsafe float comparison."
This reverts commit a5273d6992.  It was
wrong and broke the MixRamp unit test.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/844
2020-04-30 06:57:36 +02:00
Rosen Penev
47a7707df1 Math.hxx: fix wrong macro name
_GLIBCXX_USE_C99_MATH_TR1 is the correct one.

_GLIBCXX_USE_C99_MATH is always defined.
2020-04-29 23:20:04 +02:00
Max Kellermann
6fdae1139f increment version number to 0.21.24 2020-04-29 23:20:04 +02:00
skidoo23
a485c4856c decoder/sidplay: support new song length format with libsidplayfp 2.0 2020-04-29 16:27:54 +02:00
Sören Tempel
3c955639a7 doc: Document required order of currentsong response
The parser implemented in libmpdclient requires the first key-value pair
of the server response to be the file pair. This is due to the fact that
libmpdclient scan pairs sequentially and first attempts to extract the
file pair before parsing the currentsong response further. See:

	5c751a761e/src/song.c (L559-L563)

Meta data encoded as pairs in the currentsong response will be ignored
if they are placed before the file pair in the response.
2020-04-27 17:47:24 +02:00
Max Kellermann
bca9678683 tag/FixString: use IsNonPrintableASCII()
Fixes breakage of non-ASCII characters, regression from commit
cc72ceb368

Fixes https://github.com/MusicPlayerDaemon/MPD/issues/842
2020-04-27 14:01:54 +02:00
Max Kellermann
814b2a218d util/CharUtil: add IsNonPrintableASCII()
Prepare to fix cc72ceb368
2020-04-27 14:01:54 +02:00
John Regan
6423670eae gme: use song-reported fade-out time when available 2020-04-26 09:24:34 -04:00
John Regan
90a2109fd1 gme: add configurable fade-out time
Also include fade-out time in song length.
2020-04-26 09:21:57 -04:00
Max Kellermann
464b90210c tag/GenParseName: include stdlib.h for EXIT_SUCCESS
Closes https://github.com/MusicPlayerDaemon/MPD/issues/838
2020-04-24 20:39:24 +02:00
Max Kellermann
fa45a8adfa tag/ParseName: generate an optimized tag_name_parse() at build time 2020-04-24 16:28:29 +02:00
Max Kellermann
1532983fb5 tag/Pool: use strncmp() without strlen() to compare strings 2020-04-24 16:16:19 +02:00
Max Kellermann
ae5b2643da tag/Builder: reserve room in std::vector in default constructor
This reduces resource waste for resizing the std::vector in most
cases.
2020-04-24 16:16:19 +02:00
Max Kellermann
02556ffce9 tag/Tag: use class DereferenceIterator 2020-04-24 16:02:36 +02:00
Max Kellermann
18ca734819 util/DereferenceIterator: new utility class 2020-04-24 16:02:31 +02:00
Max Kellermann
8a28f7b0a1 tag/FixString: add optimistic quick check
Optimizes a few nanoseconds from the common code path.
2020-04-24 15:57:40 +02:00
Max Kellermann
cc72ceb368 tag/FixString: use IsPrintableASCII() 2020-04-24 15:42:09 +02:00
Naglis Jonaitis
c021efced1 Fix typo in documentation 2020-04-24 00:36:46 +03:00
Max Kellermann
0b3acc3eec Merge tag 'v0.21.23'
release v0.21.23
2020-04-23 18:01:23 +02:00
Max Kellermann
6c240f667c release v0.21.23 2020-04-23 17:46:20 +02:00
Max Kellermann
3040ddb5ec lib/nfs/FileReader: use struct stat64 on Windows 32-bit
libnfs is compiled with `-D_FILE_OFFSET_BITS=64`, but Meson decides
not to enable this mode.  We could force this mode, but then again,
these days, nobody should be using 32-bit Windows ... so this is a
kludge only for debugging with 32-bit WINE.
2020-04-23 17:32:34 +02:00
Max Kellermann
fdb28eb0c4 fs/NarrowPath: preserve nullptr in Path operator
Fixes Path::IsNull() checks on Windows.
2020-04-23 17:10:28 +02:00
Max Kellermann
7ded244a61 lib/nfs/Connection: pass POLLHUP and POLLERR to nfs_service() 2020-04-23 16:58:53 +02:00
Max Kellermann
8ed533acf3 event/SocketMonitor: handle epoll_ctl()=EBADF/ENOENT in Schedule()
This fixes a freeze bug in the NFS input/storage plugins: when libnfs
auto-reconnets after a failure, it installs the new socket on the same
file descriptor number.  MPD's attempt to unregister the old socket by
calling SocketMonitor::Steal() from NfsConnection::ScheduleSocket()
fails because the new/old socket number is not registered in epoll, so
epoll_ctl() returns ENOENT.  The problem is that it left
`scheduled_flags`, and so subsequent Schedule() calls will use
`EPOLL_CTL_MOD`, which will fail again and again.  Instead, we need to
use `EPOLL_CTL_ADD` to register the new socket.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/806

Closes https://github.com/MusicPlayerDaemon/MPD/issues/756
2020-04-23 16:58:26 +02:00
Max Kellermann
a27580d0cc lib/nfs/Connection: don't pass HANGUP to Schedule()
This flag is output-only.
2020-04-23 15:21:04 +02:00
Max Kellermann
905db05cf9 zeroconf/AvahiPoll: don't pass ERROR|HANGUP to Schedule()
These flags are output-only.
2020-04-23 15:19:24 +02:00
Max Kellermann
4242aee21e event/SocketMonitor: remove HANGUP|ERROR from ScheduleRead()
These flags are output-only.  Using them here is misleading.
2020-04-23 15:18:18 +02:00
Max Kellermann
e71bd2a08b event/PollGroupWinSelect: make EVENT_{READ,WRITE} static 2020-04-23 15:10:57 +02:00
Max Kellermann
e53a4d0a9e lib/nfs/FileReader: reset state in OnNfsCallback()
The object's state is `IDLE` when OnNfsCallback() gets invoked, so
let's use the start of the method to reset the `state` field.
2020-04-23 14:54:52 +02:00
Max Kellermann
159389164a lib/nfs/FileReader: set state=IDLE before invoking callback
Fixes assertion failure if the callback fails.
2020-04-23 14:51:43 +02:00
geneticdrift
0a92fbc18e tag/Fallback: add tag fallback for AlbumSort
Closes https://github.com/MusicPlayerDaemon/MPD/issues/832
2020-04-22 22:00:38 +02:00
Max Kellermann
138c29320b gme: adapt to API change in the upcoming version 0.7.0
Closes https://github.com/MusicPlayerDaemon/MPD/issues/833
2020-04-22 21:53:00 +02:00
Max Kellermann
8f00dbea45 lib/icu/Compare: add Windows implementation
Using CompareStringEx() and FindNLSStringEx().

Implements a missing piece for
https://github.com/MusicPlayerDaemon/MPD/issues/820
2020-04-22 21:42:12 +02:00
Max Kellermann
f3fd2eb618 lib/icu/Compare: use AllocatedString::Clone() 2020-04-22 21:39:13 +02:00
Max Kellermann
fc92db83cf lib/icu/Collate: use NORM_IGNORECASE instead of LINGUISTIC_IGNORECASE
LINGUISTIC_IGNORECASE is unimplemented on Wine, but since we don't
have any locale support (yet), and we're using LOCALE_NAME_INVARIANT,
NORM_IGNORECASE should essentially be the same, so why bother.
2020-04-22 21:39:13 +02:00
Max Kellermann
3b0f8d5516 lib/icu/CaseFold: remove Windows implementation
Reverts commit fb3564fbe7

LCMapStringEx() doesn't do what I imagined it would do 5 years ago.
D'oh!

Closes https://github.com/MusicPlayerDaemon/MPD/issues/820
2020-04-22 19:32:36 +02:00
Rosen Penev
a5273d6992 Fix unsafe float comparison.
Switching == to >= should be safe here since the next if is the opposite.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-04-22 18:21:40 +02:00
Rosen Penev
6979be008c [clang-tidy] use auto
Found with modernize-use-auto.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-04-22 18:21:07 +02:00
Rosen Penev
71792ffd43 [clang-tidy] use raw string
Found with modernize-raw-string-literal

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-04-22 18:21:00 +02:00
Rosen Penev
3c145c0f49 [clang-tidy] add nodiscard
Found with modernize-use-nodiscard

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-04-22 18:20:51 +02:00
Thomas Guillem
b18074f899 storage/curl: fix path comparison when the server escapes differently
Unescape the base path and the path coming from the server (href) to fix the
comparison when the server uses different escaped characters.

The outputted name need to be unescaped. Doing that before or after the
HrefToEscapedName() call should not change the current behavior.
2020-04-15 13:50:12 +02:00
Thomas Guillem
3d8067a041 storage/curl: fix href when file has a '&' char
If the file name is "Hello & bye", 3 CharacterData events will be sent with the
State::HREF state:
 - "Hello%20"
 - "&"
 - "%20bye"

Reproduced with files hosted on an apache2 DAV server: 2.4.38-3+deb10u3.
2020-04-15 13:18:16 +02:00
Florian Heese
f6fe001fa9 Added missing channel order setups for ALSA 2020-04-15 13:13:09 +02:00
Max Kellermann
55b8f2c533 NEWS: add line about Solaris change 2020-04-14 16:11:18 +02:00
Max Kellermann
32a5bf043b player/Thread: drain outputs at end of song in "single" mode
Without this, the Pause() call would drop the ring buffers and would
skip a considerable portion of the end of the song.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/824
2020-04-14 16:07:03 +02:00
nia
8437b141a4 SolarisOutputPlugin: Support S8 and S32 encodings. 2020-04-14 14:38:30 +01:00
nia
1f0881eec0 SolarisOutputPlugin: Use AUDIO_INITINFO for initialization
This is recommended by Solaris and NetBSD documentation.
2020-04-14 14:20:24 +01:00
Max Kellermann
8d2079482f Merge branch 'lkj' of git://github.com/neheb/MPD into v0.21.x 2020-04-14 13:12:42 +02:00
Max Kellermann
c331c75fde increment version number to 0.21.23 2020-04-14 13:12:36 +02:00
Rosen Penev
6080c3b4ba Math.hxx: move cmath include out of define
The _GLIBCXX_USE_C99_MATH macro is defined in glibcxx by c++config.h, which
gets included by every header. Which means a header needs to be present.

(cherry picked from commit 79e9aff338)
2020-04-09 14:24:06 -07:00
Max Kellermann
3c240e2119 db/simple/DirectorySave: pass std::string_view to _load_subdir()
Eliminates one strlen() call.
2020-04-08 23:54:58 +02:00
Max Kellermann
57fb153c5d db/Interface: pass std::string_view to GetSong() 2020-04-08 23:43:59 +02:00
Max Kellermann
212401d687 db/update/Service: pass std::string_view to Enqueue() 2020-04-08 23:38:28 +02:00
Max Kellermann
dd831d3922 db/simple: pass std::string_view to Directory::LookupDirectory() 2020-04-08 23:38:24 +02:00
Max Kellermann
9f8dc31b50 input/Plugin: copy protocols() to stack before using it
Fixes regression by commit 015cbff93d causing a crash bug because the
iterators of two different temporaries were used.
2020-04-08 23:37:32 +02:00
Max Kellermann
db93bb996c util/SplitString: convert return value to std::string_view
Eliminates lots of overhead.
2020-04-08 23:14:25 +02:00
Max Kellermann
2c02a04566 db/update/Walk: pass std::string_view to DirectoryMakeUriParentChecked()
Split the string into path segments with StringView::Split().  This
prepares to eliminate all allocations from the method.
2020-04-08 23:09:37 +02:00
Max Kellermann
f13f66487a fs/Charset: pass std::string_view to PathToUTF8() 2020-04-08 23:04:37 +02:00
Max Kellermann
0a4c5edc3b Merge branch 'stl' of git://github.com/neheb/MPD 2020-04-08 23:03:44 +02:00
Rosen Penev
015cbff93d [cppcheck] convert several functions to use std::all_of
std::all_of becomes constexpr in C++20. I'm not sure it results in better
performance.

Found with useStlAlgorithm

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-04-08 14:01:12 -07:00
Rosen Penev
79e9aff338 Math.hxx: move cmath include out of define
The _GLIBCXX_USE_C99_MATH macro is defined in glibcxx by c++config.h, which
gets included by every header. Which means a header needs to be present.
2020-04-07 20:14:00 -07:00
Max Kellermann
3a51fe31df util/ConstBuffer, ...: use using instead of typedef 2020-04-06 15:19:12 +02:00
Max Kellermann
cc3e71d8c7 util/CharUtil: add IsHexDigit() 2020-04-06 15:07:08 +02:00
Max Kellermann
dd37b4656e storage/{composite,local}: fix -Wnonnull warnings 2020-04-06 15:06:52 +02:00
Max Kellermann
e2d2bb8755 storage/Composite: use IterableSplitString() 2020-04-03 19:51:14 +02:00
Max Kellermann
a98d627c0b storage/Interface: convert URI parameters to std::string_view 2020-04-03 19:45:10 +02:00
Max Kellermann
0080eee857 fs/Traits: add Relative() overload with std::string_view 2020-04-03 19:45:01 +02:00
Max Kellermann
2429cc8778 fs/Traits: convert first Relative() parameter to std::string_view 2020-04-03 19:29:29 +02:00
Max Kellermann
3a83a6b527 storage/Composite: NextSegment() returns std::string_view 2020-04-03 19:29:01 +02:00
Max Kellermann
bcf4645263 db/simple/Directory: add LookupResult::uri 2020-04-03 17:18:00 +02:00
Max Kellermann
6c8eb3c7ed db/simple/Directory: rename LookupResult::uri to "rest" 2020-04-03 17:07:15 +02:00
Max Kellermann
870151214d util/SplitString: convert parameter to std::string_view 2020-04-03 16:47:45 +02:00
Max Kellermann
ae4fd576bf output/ao: use IterableSplitString() instead of SplitString() 2020-04-03 16:47:25 +02:00
Max Kellermann
747436b17e db,storage: pass std::string_view to PathTraits::Build() 2020-04-03 16:25:09 +02:00
Max Kellermann
7a58b8c3e8 fs/AllocatedPath: pass std::string_view to FromUTF8() 2020-04-03 16:21:41 +02:00
Max Kellermann
56b4b010d6 fs/FileSystem, ...: use AllocatedPath::FromFS(string_view) 2020-04-03 16:13:15 +02:00
Max Kellermann
91c75a133f lib/icu/Collate: pass std::string_view 2020-04-03 16:13:15 +02:00
Max Kellermann
e620677d7c lib/icu/CaseFold: pass std::string_view 2020-04-03 16:13:14 +02:00
Max Kellermann
09d8e44d56 lib/icu/Converter: pass std::string_view 2020-04-03 16:13:14 +02:00
Max Kellermann
9dc530ab51 lib/icu/Util: pass std::string_view 2020-04-03 16:13:14 +02:00
Max Kellermann
2d0798cd4d lib/icu/Win32: pass std::string_view 2020-04-03 16:13:14 +02:00
Max Kellermann
a269fc988b fs/Charset: enable RVO in FixSeparators() 2020-04-03 16:12:51 +02:00
Max Kellermann
915c48f748 util/AllocatedString: std::string_view support 2020-04-03 16:08:55 +02:00
Max Kellermann
f04a245769 util/AllocatedString: add noexcept 2020-04-03 15:26:47 +02:00
Max Kellermann
a8687fb7df util/AllocatedString: use using instead of typedef 2020-04-03 15:25:37 +02:00
Max Kellermann
3b88bac07c util/StringPointer: add noexcept 2020-04-03 15:25:33 +02:00
Max Kellermann
358f231391 util/StringPointer: use using instead of typedef 2020-04-03 15:25:16 +02:00
Max Kellermann
f0923231d0 storage/Interface: pass std::string_view to MapChildFS() 2020-04-02 20:14:00 +02:00
Max Kellermann
dadf054fbb db/simple/Directory: reimplement LookupDirectory() without allocations
Use std::string_view to avoid modifying the string for the temporary
null terminators.
2020-04-02 20:08:00 +02:00
Max Kellermann
6593b5998a db/simple/Directory: pass std::string_view to several methods 2020-04-02 19:58:24 +02:00
Max Kellermann
386235e2d2 db/simple/Mount: pass std::string_view to WalkMount() 2020-04-02 19:52:03 +02:00
Max Kellermann
ddfd92e547 db/simple/PrefixedLightSong: templatize the constructor 2020-04-02 19:51:41 +02:00
Max Kellermann
d5fd309484 db/update/IO: pass std::string_view to directory_child_is_regular() 2020-04-02 19:50:16 +02:00
Max Kellermann
6197b29aa0 db/PlaylistInfo: pass std::string_view to CompareName 2020-04-02 19:49:39 +02:00
Max Kellermann
02294a8236 song/Filter: pass std::string_view to WithoutBasePrefix() 2020-04-02 19:49:24 +02:00
Max Kellermann
66bcf04cbd db/update/Queue: pass std::string_view to Push() 2020-04-02 19:49:16 +02:00
Max Kellermann
12b97bbe38 Merge tag 'v0.21.22'
release v0.21.22
2020-04-02 18:02:10 +02:00
Max Kellermann
5ccfcffcc1 release v0.21.22 2020-04-02 17:48:56 +02:00
Max Kellermann
afe2aaa5f6 fs/io/GzipOutputStream: increase buffer size to 16 kB
Reduce I/O overhead.
2020-04-02 17:17:58 +02:00
Max Kellermann
9b11caa0e6 fs/io/BufferedReader: larger default buffer (4 kB -> 16 kB)
Reduce I/O overhead.
2020-04-02 17:17:27 +02:00
Max Kellermann
a689b881d3 test/meson.build: work around linker failure due to statically linked CURL 2020-04-02 17:16:05 +02:00
Max Kellermann
e94c436264 src/event/meson.build: depend in libnet.a
The event library uses various libnet.a classes,
e.g. SocketDescriptor.
2020-04-02 17:16:05 +02:00
Max Kellermann
bad829509e test/ShutdownHandler: add inline to work around Windows linker problems 2020-04-02 17:16:05 +02:00
Max Kellermann
9c66b0414a test/*: fix Windows build using class FromNarrowPath 2020-04-02 17:16:05 +02:00
Max Kellermann
4d453a8313 fs/NarrowPath: add class FromNarrowPath
Move code from ParseCommandLine().
2020-04-02 17:15:34 +02:00
Max Kellermann
61d7b436a2 fs/NarrowPath: un-inline Windows constructor 2020-04-02 16:27:44 +02:00
Max Kellermann
cdddaf21b0 db/simple/Directory: optimize GetName() using the parent's path
This method gets called a lot during MPD startup, via FindChild() and
directory_load_subdir(), so this is worth optimizing at the expense of
code readability.

This speeds up MPD startup by 10%.
2020-04-02 16:12:08 +02:00
Max Kellermann
b267ba5f0a tag/Pool: enlarge hash table
This consumes more memory (plus 48 kB on 32 bit systems), but reduces
the number of hash collisions, speeding up MPD startup with large
databases.
2020-04-02 15:45:35 +02:00
Max Kellermann
8270043053 Revert "decoder/ffmpeg: copy the AVPacket in ffmpeg_send_packet()"
This reverts commit eb192137d6.

This is no longer necessary because we require FFmpeg 3.1 or newer
since MPD 0.21.2.

This fixes a deprecation warning because the implicit AVPacket copy
constructor copies the deprecated attribute `convergence_duration`.
2020-04-01 17:30:28 +02:00
Max Kellermann
c00ce42bca python/build/libs.py: update libmpdclient to 2.18 2020-04-01 17:17:30 +02:00
Max Kellermann
3852ddbbce .travis.yml: install more packages on OSX
Enable lots of plugins for better CI coverage.
2020-04-01 16:37:45 +02:00
Max Kellermann
672bc3ab67 time/Convert: fix GetTimeZoneOffset() on Windows
Was using the wrong parameter.
2020-04-01 16:21:29 +02:00
Max Kellermann
62229f14da test/time: add test for LocalTime(), GmTime() 2020-04-01 16:21:29 +02:00
Max Kellermann
a4c925c8d7 test/meson.build: move TestTime to time/ 2020-04-01 16:12:01 +02:00
Max Kellermann
60610e90b1 test/net/TestIPv[46]Address: fix Windows build errors 2020-04-01 16:09:24 +02:00
Max Kellermann
90184e0ce7 python/build/libs.py: update CURL to 7.69.1 2020-04-01 15:49:16 +02:00
Max Kellermann
7d7bd51bc0 util/AllocatedArray: use using instead of typedef 2020-04-01 15:42:55 +02:00
Rosen Penev
71e551df42 replace locale.h with clocale
Switch to std:: functions. Changed the meson check. Works locally.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-31 18:05:23 -07:00
Max Kellermann
9c3e1d450a fs/io/GunzipReader: increase buffer size to 64 kB
Reduces I/O overhead while reading a compressed database file.
2020-03-31 15:07:39 +02:00
Rosen Penev
3540cf26b1 replace exit and _exit with std variants
_exit and std::_Exit are identical, expect the latter is standard C++.

Added several functions to the std namespace as a result of headers.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-26 18:44:09 -07:00
Thomas Guillem
60f2116202 android/Settings: remove the EXPIRIMENTAL text
Using MPD from Android since quite some times now. I consider it very stable
now.
2020-03-26 17:31:31 +01:00
Thomas Guillem
4ff2532330 android: add TV support
TODO: Not sure the app could be accepted on the play store without a valid
banner.
2020-03-26 17:31:20 +01:00
Thomas Guillem
9c15760c4d android/Main: handle API26 NotificationChannel
This seems to be required on recent Android versions (tested with Android 10).
This is also required for android TV services (cf. next commit).

This is done using Java reflection so that the project doesn't depend on
android compat libs.
2020-03-26 17:30:55 +01:00
Max Kellermann
e1c43ec65f Merge branch 'ucl' of git://github.com/neheb/MPD into v0.21.x 2020-03-26 17:28:21 +01:00
Thomas Guillem
4dd10894ba lib/curl/Request: fix Exception "error" on Android
Apparently, it's not possible to change CURLOPT_NETRC on Android.
2020-03-26 17:26:14 +01:00
Rosen Penev
608d7ec1e7 [clang-tidy] change integer prefixes to uppercase
Found with readability-uppercase-literal-suffix

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-26 17:25:20 +01:00
Max Kellermann
8474599ed6 lib/curl/Easy: add method Unpause() 2020-03-26 17:22:10 +01:00
Max Kellermann
ab39f64fc0 lib/curl/Easy: add setter functions 2020-03-26 17:21:30 +01:00
Max Kellermann
185fbca282 lib/curl/Global: make ReadInfo() private 2020-03-26 17:20:10 +01:00
Max Kellermann
6e3b2fd844 lib/curl/Global: remove redundant API docs 2020-03-26 17:20:06 +01:00
Max Kellermann
dab39dc778 lib/curl: fix coding style 2020-03-26 17:19:48 +01:00
Max Kellermann
8cd5e79fbd event/*, ...: make GetEventLoop() const 2020-03-26 17:19:13 +01:00
Max Kellermann
1de3ac6c78 lib/curl/Init: add const overloads 2020-03-26 17:18:27 +01:00
Max Kellermann
abe06a5fa6 lib/curl/Init: add noexcept 2020-03-26 17:18:23 +01:00
Rosen Penev
85c27840a3 treewide: use boost::lround when std::round is unavailable
This is the case with uClibc-ng currently.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
(cherry picked from commit 769cd0ee9f0cf8ceb026aa751b5d4a390bb5dbdc)
(changed define to match master)
2020-03-25 18:54:15 -07:00
Thomas Guillem
81c16273c5 output/sles: use the AndroidMixerPlugin 2020-03-25 20:08:53 +01:00
Thomas Guillem
801ae86b5d mixer: add AndroidMixerPlugin 2020-03-25 20:07:26 +01:00
Thomas Guillem
5619fd0bba android: Context: add GetAudioManager 2020-03-25 20:07:25 +01:00
Thomas Guillem
200258c7c3 android: add AudioManager 2020-03-25 20:07:24 +01:00
Max Kellermann
5418bb49fb android/Context: add noexcept 2020-03-25 20:07:18 +01:00
Max Kellermann
3449c14ff5 java/Object: rename class Object to GlobalObject 2020-03-25 20:07:15 +01:00
Rosen Penev
cfa4524cb3 util/Math: change define
This has nothing to do with uClibc. It has everything to do with gcc's
libstdc++.

C99 math can be compile time disabled for it. Check for that and use boost
lround when std is not available.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-25 19:27:45 +01:00
Rosen Penev
4fd0c84f46 replace lrint with lround
lrint is a configurable version of lround that behaves either as round,
floor, ceil, or trunc based on setting the proper FE_ macro using
fset/getround. Given that it's not set at all and that it defaults to
round behavior, simply replace with round.

Also removed the util/Math defines.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-25 19:27:44 +01:00
Rosen Penev
e41a52d909 change abs() to std::abs()
Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-25 19:27:42 +01:00
Rosen Penev
01e00632cc [cppcheck] fix format string
Found with invalidPrintfArgType_sint

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-25 19:27:40 +01:00
Rosen Penev
9bad5ee3c5 remove boost pow stuff for uClibc-ng
It's available there.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-24 17:21:21 -07:00
Rosen Penev
e87454ae88 MpcdecDecoderPlugin: use std variant of pow
It's available with uClibc-ng. It also offers overloads.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-24 17:16:51 -07:00
Rosen Penev
f319f88df4 [cppcheck] use const for several variables
Found with constVariable

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-23 21:03:22 -07:00
Max Kellermann
637840264a util/WStringCompare: reorder functions to relocate API docs 2020-03-22 19:20:29 +01:00
Max Kellermann
3888bafc1f util/StringCompare: add API documentation 2020-03-22 19:15:55 +01:00
Max Kellermann
adad4c7298 util/StringCompare: add missing include 2020-03-22 19:12:02 +01:00
Max Kellermann
d54acbcffd Merge branch 'sles-assert-fix' of git://github.com/tguillem/MPD-1 2020-03-22 10:51:28 +01:00
kowalcj0
36a89e8fe7 Support RSS feeds with application/xml MIME-type 2020-03-22 10:49:38 +01:00
Max Kellermann
8e6a21a9c2 increment version number to 0.21.22 2020-03-22 10:48:53 +01:00
Thomas Guillem
86613af37e output/sles: fix invalid assert
Regression from 973c87b351
2020-03-21 22:34:04 +01:00
Rosen Penev
ba3ff10ccd remove false ifdef
The entire section falls under the else path of #ifdef _WIN32. Checking
for it makes no sense. Probably some refactoring mistake.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-20 17:56:33 -07:00
Max Kellermann
1ec283d213 util/Exception: include cleanup 2020-03-19 20:13:04 +01:00
Max Kellermann
2261bcb5d3 android/Environment: remove another extra semicolon 2020-03-19 20:13:04 +01:00
Max Kellermann
0e17629445 android/Environment: remove extra semicolon 2020-03-19 15:27:43 +01:00
Max Kellermann
0da6344726 Merge tag 'v0.21.21'
release v0.21.21
2020-03-19 15:26:27 +01:00
Max Kellermann
c560ec8ea6 release v0.21.21 2020-03-19 15:22:28 +01:00
Rosen Penev
cade4e71c4 [clang-tidy] add [[nodiscard]]
Found with modernize-use-nodiscard

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-19 13:38:40 +01:00
Rosen Penev
403612c666 [clang-tidy] run through performance checks
Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-19 13:38:40 +01:00
Rosen Penev
7fe49cf24d [clang-tidy] use default member init
Found with modernize-use-default-member-init

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-19 13:38:40 +01:00
Rosen Penev
d2115e908a [clang-tidy] remove redundant access specifiers
Found with readability-redundant-access-specifiers

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-19 13:38:40 +01:00
Max Kellermann
56c234b410 raise default "max_connections" value to 100
Documentation says the limit is 5, but it was really 10 (at least
since 2004).  But since MPD wants to promote using many small clients
idling around, and these clients consume only very few resources, it
seems reasonable to raise this limit's default value.
2020-03-19 13:30:46 +01:00
Max Kellermann
61b5ab2663 thread/CriticalSection: remove extra semicolons 2020-03-17 16:57:57 +01:00
Rosen Penev
84f71cec2c add two extra noreturn that clang picked up
Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-16 23:02:35 -07:00
Rosen Penev
a5b136c420 test: fix double promotion
Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-16 22:56:30 -07:00
Rosen Penev
c7144ed5c7 add recently fixed warnings to warning list
Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-16 22:56:29 -07:00
Rosen Penev
00b9f69c90 remove some more extra semicolons
Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-16 13:37:13 -07:00
Rosen Penev
6d91b5c7b2 fix double promotions
Found with -Wdouble-promotion

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-16 12:43:24 -07:00
Max Kellermann
fd71514068 Merge remote-tracking branch 'neheb/h' 2020-03-16 17:29:05 +01:00
Max Kellermann
256cfc545d Merge remote-tracking branches 'neheb/fwhfggwe', 'neheb/nvm2', 'neheb/nvm22', 'neheb/bvm' and 'neheb/cl2' 2020-03-16 17:25:50 +01:00
Rosen Penev
77c6c3fabf remove unreachable code
Found with -Wunreachable-code-break

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-16 00:14:13 -07:00
Rosen Penev
e25a3d17e7 remove extra semicolon
Found with -Wextra-semi

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-16 00:13:20 -07:00
Rosen Penev
7f10e7a610 fix implicit-fallthrough warnings under clang
Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-16 00:12:38 -07:00
Rosen Penev
88d56c01e7 fix missing overrides
Found with clang's -Winconsistent-missing-destructor-override

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-16 00:11:15 -07:00
Rosen Penev
97425d56e7 remove gcc_unused
[[maybe_unused]] (introduced in C++17) is standard C++.

https://clang.llvm.org/docs/AttributeReference.html#maybe-unused-unused
says that this is equivalent to the GNU unused attribute.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-16 00:08:21 -07:00
Rosen Penev
0afb156a5b remove gcc_warn_unused
[[nodiscard] (introduced in C++17) can be used instead.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-16 00:08:21 -07:00
Rosen Penev
a192e7b29b remove gcc_deprecated
[[deprecated]] (introduced in C++14) may be used instead.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-16 00:08:21 -07:00
Rosen Penev
591f51f3d3 replace noreturn attribute with standard C++ version
Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-16 00:08:18 -07:00
Rosen Penev
5e4b7e2fb7 [clang-tidy] fix incorrect rounding
Found with bugprone-incorrect-roundings

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-15 20:22:08 -07:00
Rosen Penev
177371a003 treewide: get rid of C math function usage
Boost does not seem to offer an overload for lrint.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-15 20:22:07 -07:00
Rosen Penev
a78841d6a9 volume_mapping: get rid of exp10 workaround
exp10 is a GNU function, is not part of C++, and is not available
everywhere.

pow(10,x) is an alternative that works just as well. It is used in musl as
the implementation of exp10.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-15 20:17:31 -07:00
Rosen Penev
3ec9fcfc44 treewide: use boost::lround when std::round is unavailable
This is the case with uClibc-ng currently.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-15 20:17:31 -07:00
Max Kellermann
b5d1a09010 util/StringUtil: pass std::string_view to StringArrayContainsCase() 2020-03-13 20:38:40 +01:00
Max Kellermann
85b072b3d3 util/StringCompare: add StringIsEqual() with string_view 2020-03-13 20:36:48 +01:00
Max Kellermann
8a1f1fbe06 util/ASCII: migrate to std::string_view 2020-03-13 20:17:53 +01:00
Max Kellermann
45b60b3d38 fs/Traits: GetParent() returns std::string_view 2020-03-13 20:01:10 +01:00
Max Kellermann
cefc773992 playlist/PlaylistSong: pass std::string_view 2020-03-13 19:58:36 +01:00
Max Kellermann
a885bdba4c fs/Traits: pass string_view to Build() 2020-03-13 19:55:28 +01:00
Max Kellermann
b6b15afb5a fs/Path: make constructor explicit 2020-03-13 19:55:25 +01:00
Max Kellermann
1d560c8f0f fs/AllocatedPath: add string_view constructor 2020-03-13 19:46:29 +01:00
Max Kellermann
189f6eaa6f fs/Traits: add string_view 2020-03-13 19:43:39 +01:00
Max Kellermann
87f78b9c39 fs/Traits: use {} notation for return values 2020-03-13 19:43:23 +01:00
Max Kellermann
aa722bd8ac fs/Traits: use auto 2020-03-13 19:43:23 +01:00
Max Kellermann
58c7ec07a4 fs: use using instead of typedef 2020-03-13 19:43:23 +01:00
Max Kellermann
3796247d6d util/Stringview: use const_pointer instead of hard-coding const char *
Fixes Windows build failure.
2020-03-13 19:43:23 +01:00
Max Kellermann
332f480ec3 util/UriExtract: uri_get_path() returns std::string_view 2020-03-13 18:54:41 +01:00
Max Kellermann
9a164668f2 util/UriExtract: migrate uri_get_scheme() to std::string_view 2020-03-13 18:51:11 +01:00
Max Kellermann
6876d160cf util/StringCompare: add more StringView overloads 2020-03-13 18:49:47 +01:00
Max Kellermann
a63d0ee8fc util/StringView: add method substr() 2020-03-13 18:48:40 +01:00
Max Kellermann
d4135935e4 lib/upnp/Util: remove unused function stringToTokens() 2020-03-13 17:59:07 +01:00
Max Kellermann
569773cc75 lib/upnp/Device: remove UPnPService::clear() 2020-03-13 17:56:29 +01:00
Rosen Penev
a2f5a63bbc replace stdint.h with cstdint
The former is deprecated by C++14. The standard says they are the same:

The header defines all types and macros the same as the C standard library
header<stdint.h>.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-12 19:04:39 -07:00
Rosen Penev
2db8bcc353 replace stddef.h with cstddef
The former is deprecated with C++14. The standard says both are the same:

The contents and meaning of the header<cstddef>are the same as the C
standard library header<stddef.h>,except that it does not declare the type
wchar_t, that it also declares the type byte and its associated
operations (21.2.5), and as noted in 21.2.3 and 21.2.4.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-12 19:04:38 -07:00
Rosen Penev
c846ee0d1b replace stdarg.h with cstdarg
The former was deprecated in C++14. The Standard says they are the same:

The contents of the header<cstdarg>are the same as the C standard library
header<stdarg.h>, with the following changes: The restrictions that ISO C
places on the second parameter to the va_start macro in header<stdarg.h>
are different in this International Standard. The parameter parmN is the
rightmost parameter in the variable parameter list of the function
definition (the one just before the...).219If the parameter parmN is a
pack expansion (17.5.3) or an entity resulting from a lambda capture
(8.1.5), the program is ill-formed, no diagnostic required. If the
parameter parmN is of a reference type, or of a type that is not
compatible with the type that results when passing an argument for which
there is no parameter, the behavior is undefined.

Also changed va_list to the std:: namespace version, which is the same.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-12 19:03:12 -07:00
Rosen Penev
69a51e12c9 replace signal.h with csignal.h
The former was deprecated with C++14. The standard says they are the same:

The contents of the header<csignal>are the same as the C standard library
header<signal.h>.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-12 18:56:51 -07:00
Rosen Penev
4b57b7f5a5 replace limits.h with climits
The former was deprecated with C++14. The standard says they are the same
with one exception:

The header<climits>defines all macros the same as the C standard library
header<limits.h>.

[Note:The types of the constants defined by macros in<climits>are not
required to match the types to which themacros refer.— end note]

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-12 16:14:04 -07:00
Rosen Penev
5cd400f578 replace inttypes.h with cinttypes
The former has been deprecated by C++14. They are also the same.

From the standard:

The contents and meaning of the header<cinttypes>are the same as the C
standard library header<inttypes.h>, with the following changes:

-The header<cinttypes>includes the header<cstdint>instead of<stdint.h>,and
—if and only if the typeintmax_tdesignates an extended integer type
 (6.7.1), the following functionsignatures are added:intmax_t
abs(intmax_t);imaxdiv_t div(intmax_t, intmax_t);which shall have the same
semantics as the function signaturesintmax_t imaxabs(intmax_t)andimaxdiv_t
imaxdiv(intmax_t, intmax_t), respectively.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-12 16:07:28 -07:00
Rosen Penev
edc4989d9c change errno.h to cerrno
The former is deprecated by C++14. It's also functionally the same.

From the standard:

19.4
The header<cerrno>is described in Table 43. Its contents are the same as
the POSIX header<errno.h>,except that errno shall be defined as a macro.
[Note: The intent is to remain in close alignment with the POSIX
standard.] A separate errno value shall be provided for each thread.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-12 15:51:16 -07:00
Rosen Penev
2b3d6461e3 remove unused ctype.h header
None of the functions in these files come from ctype.h

Also changed one instance of isdigit to the C++ variant.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-12 15:43:50 -07:00
Rosen Penev
ab9f5d2067 replace assert.h with cassert
The former was deprecated with C++14.

According to the C++11 and C++17 standards, both files are identical.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-12 15:25:38 -07:00
Max Kellermann
a718086ffb test/run_convert: add option --config 2020-03-12 21:41:39 +01:00
Max Kellermann
8d40e68dec test/run_convert: add option --verbose 2020-03-12 21:41:39 +01:00
Max Kellermann
de0affe115 test/run_convert: move code to ParseCommandLine() 2020-03-12 21:40:27 +01:00
Max Kellermann
26e718c7c3 doc/user.rst, .travis.yml: drop GCC 6 support
Debian Stable (Buster) has GCC 8 and Ubuntu LTS (18.04) has GCC 7.

This will unlock a lot of C++17 features like `std::string_view`.
2020-03-12 21:37:07 +01:00
Max Kellermann
82743dfd02 playlist/asx: concatenate multiple CharacterData fragments
Similar to c45f113856
2020-03-12 21:07:37 +01:00
Rosen Penev
f00f8b002a [clang-tidy] use nodiscard
Introduced in C++17. It replaces gcc's warn_unused_result.

Found with modernize-use-nodiscard.

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-03-12 12:59:16 -07:00
Max Kellermann
33694642bd playlist/asx: add State::TAG 2020-03-12 20:42:16 +01:00
Max Kellermann
c71242d743 playlist/asx: use tag_table to convert element name to TagType 2020-03-12 20:40:18 +01:00
Max Kellermann
2229e86673 client/Expire: cancel the BackgroundCommand before deleting it
Fixes assertion failure.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/774
2020-03-12 20:32:08 +01:00
Max Kellermann
f24c274f5c client/BackgroundCommand: fix typo in comment 2020-03-12 20:32:07 +01:00
Max Kellermann
3824bf66ca lib/chromaprint/DecoderClient: add assertion 2020-03-12 20:32:07 +01:00
Max Kellermann
d942f874ae lib/chromaprint/DecoderClient: check ready in GetCommand()
Fixes access to uninitialized memory (`remaining_bytes` isn't
initialized until Ready() is called) and fixes spurious
`getfingerprint` failures.
2020-03-12 20:31:46 +01:00
Max Kellermann
01632d37ef Merge branch 'v0.21.x' 2020-03-12 08:11:08 +01:00
Max Kellermann
c45f113856 playlist/xspf: concatenate multiple CharacterData fragments
Closes https://github.com/MusicPlayerDaemon/MPD/issues/781
2020-03-12 08:02:58 +01:00
Max Kellermann
e0a8fd398c playlist/xspf: add State::TAG 2020-03-12 08:00:54 +01:00
Max Kellermann
3e97058151 playlist/xspf: move location.empty() check to _start_element() 2020-03-11 20:54:53 +01:00
Max Kellermann
51b1dd8672 playlist/xspf: use tag_table to convert element name to TagType 2020-03-11 20:51:47 +01:00
Max Kellermann
98a7d8da6c playlist/xspf: use C++11 initializer 2020-03-11 20:51:10 +01:00
Max Kellermann
acb29f792f tag/Mask: fix yet another typo, this time in Unset()
Similar to commits e8f2f98048 and
ff1ff1e54a

Closes https://github.com/MusicPlayerDaemon/MPD/issues/783
2020-03-11 20:34:02 +01:00
Max Kellermann
cd364023ae .travis.yml: rename "matrix" to "jobs"
Travis has changed the canonical name for this a while ago.

(Now really.  The last commit for this was empty.)
2020-03-07 09:31:46 +01:00
Max Kellermann
8d34a1cfc6 archive/iso9660: skip empty filenames
Aparently, libcdio sometimes returns empty filenames, causing MPD
crashes.  This shouldn't really happen, and I consider this a libcdio
bug - but if it happens, people blame MPD, so let's add a check.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/776
2020-03-07 09:30:56 +01:00
Max Kellermann
73a1f078a6 archive/iso9660: use IsSpecialFilename() 2020-03-07 09:30:56 +01:00
Max Kellermann
b7ce452308 fs/Traits: add IsSpecialFilename()
Merge some duplicate code in a central library.
2020-03-07 09:30:56 +01:00
Max Kellermann
5faf76051d .travis.yml: force updating homebrew on OSX
Workaround for Travis failures as described in
 https://travis-ci.community/t/macos-build-fails-because-of-homebrew-bundle-unknown-command/7296/18
2020-03-07 09:30:56 +01:00
Max Kellermann
5fe70a3417 .travis.yml: rename "matrix" to "jobs"
Travis has changed the canonical name for this a while ago.
2020-03-07 09:30:56 +01:00
Thomas Klausner
7a68b1e71f Adapt SolarisOutputPlugin.cxx to be usable on NetBSD. 2020-02-29 10:05:29 +01:00
Thomas Klausner
d5468dfe89 Add missing header.
Fixes
../src/time/ISO8601.cxx:67:24: error: use of undeclared identifier 'strtoul'
        unsigned long value = strtoul(s, &endptr, 10);
                              ^
../src/time/ISO8601.cxx:77:14: error: use of undeclared identifier 'strtoul'
                        minutes = strtoul(s, &endptr, 10);
                                  ^

on NetBSD with clang 9.0.0.
2020-02-29 10:04:54 +01:00
John Regan
976372ff63 gme: check for empty metadata strings instead of nullptr
Using libgme 0.6.2 on macOS, it appears that gme_info_t strings can be
empty, which creates weird track titles: (001/050)

This adds an additional check for an empty string.
2020-02-25 20:12:08 +01:00
Max Kellermann
c977d646c7 Merge remote-tracking branches 'neheb/j', 'neheb/f', 'neheb/qwe' and 'neheb/hgf' 2020-02-20 16:58:17 +01:00
Rosen Penev
ac50bb5d2b [clang-tidy] remove needless std::move
Found with performance-move-const-arg

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-02-20 16:47:34 +01:00
Max Kellermann
85e33f7d60 lib/dbus/Udisks2: make path non-const to allow moving from it 2020-02-20 16:47:32 +01:00
Max Kellermann
7646866a32 neighbor/smbclient: make iterators non-const to enable the std::move() 2020-02-20 16:47:32 +01:00
Max Kellermann
d072b3cb17 storage/smbclient: remove misplaced .c_str() call 2020-02-20 16:47:32 +01:00
Max Kellermann
646fef108a storage/composite: make variable non-const to enable the std::move() 2020-02-20 16:41:38 +01:00
Max Kellermann
d1cc73775f Instance: flush input cache on SIGHUP 2020-02-17 15:23:05 +01:00
Max Kellermann
29d05cdb8e unix/SignalHandlers: pass Instance to ...Init() 2020-02-17 15:23:03 +01:00
Max Kellermann
322d6f2a40 doc/user.rst: add section "Signals" 2020-02-17 15:22:45 +01:00
Max Kellermann
7729713924 doc/user.rst: add section "Starting MPD"
Move the existing systemd sections over there.
2020-02-17 12:21:05 +01:00
Rosen Penev
351a4a80d2 [clang-tidy] use using instead of typedef
Found with modernize-use-using

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-02-16 19:22:32 -08:00
Rosen Penev
87f7b0f0bb [clang-tidy] use emplace_back
Found with hicpp-use-emplace

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-02-16 19:21:55 -08:00
Rosen Penev
6d3190fe5f [clang-tidy] use = default
Found with modernize-use-equals-default

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-02-16 17:10:18 -08:00
Rosen Penev
5d787806fe [clang-tidy] add ending namespace comments
Found with llvm-namespace-comment

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-02-16 16:44:37 -08:00
Max Kellermann
9abb686eeb increment version number to 0.21.21 2020-02-16 20:48:46 +01:00
Max Kellermann
dea0cc165d input/cache/Manager: add method Flush() 2020-02-16 20:46:24 +01:00
Max Kellermann
07e0a31d02 Merge tag 'v0.21.20'
release v0.21.20
2020-02-16 20:46:13 +01:00
Max Kellermann
f24bcc7f42 release v0.21.20 2020-02-16 20:43:35 +01:00
Max Kellermann
89800324cb .travis.yml: use GTest 1.8.0 instead of HEAD
Fixes strange C++11 compatibility problems during GTest installation:

 /tmp/gtest-20200216-20679-mu1044/googletest/include/gtest/internal/gtest-internal.h:1249:1: error: unknown type name 'constexpr'
 constexpr bool TypedTestCaseIsDeprecated() { return true; }

 /tmp/gtest-20200216-20679-mu1044/googletest/include/gtest/internal/gtest-internal.h:1249:11: error: expected unqualified-id
 constexpr bool TypedTestCaseIsDeprecated() { return true; }

 /tmp/gtest-20200216-20679-mu1044/googletest/include/gtest/internal/gtest-internal.h:1254:1: error: unknown type name 'constexpr'
 constexpr bool RegisterTypedTestCase_P_IsDeprecated() { return true; }
2020-02-16 20:33:15 +01:00
Rosen Penev
050e30418c Fix travis
pip is bugged on arm64 and s390x. Add --no-cache-dir to fix. For
consistency, it doesn't hurt to add everywhere.
2020-02-16 19:29:30 +01:00
Max Kellermann
36a678276b storage/composite: no "=default" in constructor
Closes https://github.com/MusicPlayerDaemon/MPD/pull/739 (essentially
the same, but with a proper explanation)
2020-02-16 19:07:08 +01:00
Max Kellermann
d4a6d647a0 Merge branch 'efuhgeh' of git://github.com/neheb/MPD 2020-02-16 19:03:35 +01:00
Max Kellermann
5397d18ed9 protocol/ArgParser: cast seek offset to SignedSongTime
"The issue is that ParseCommandArgSignedSongTime parses with
SongTime::FromS, not SignedSongTime::FromS, before casting back to a
SignedSongTime for the return. With x86 overflow rules this doesn't
matter, but on ARM the first cast turns negative values to zero."

Closes https://github.com/MusicPlayerDaemon/MPD/issues/757
2020-02-10 09:18:37 +01:00
Max Kellermann
2d3b51665e util/BitReverse: generate table with constexpr function
Get rid of the macro hell.
2020-02-05 19:51:46 +01:00
Max Kellermann
7b03f55cb4 util/bit_reverse: convert to C++ 2020-02-05 19:49:18 +01:00
Max Kellermann
b84444b680 archive/iso9660: rewrite the macro CEILING as function 2020-02-05 19:43:20 +01:00
Max Kellermann
1e421cbcb2 Merge remote-tracking branches 'neheb/patch-2', 'neheb/con', 'neheb/cons', 'neheb/guruhg', 'neheb/r12R3', 'neheb/fefgheh' and 'neheb/rhgerg3453' 2020-02-05 19:36:01 +01:00
Rosen Penev
a4eed3e330 [clang-tidy] use forward instead of move
Found with bugprone-move-forwarding-reference

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-02-04 18:31:00 -08:00
Rosen Penev
b9db8ddee6 [clang-tidy] remove misplaced const
The rhs evaluates to void *const, not const void*.

Found with misc-misplaced-const

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-02-04 15:27:14 -08:00
Rosen Penev
9cf1385765 [clang-tidy] remove static in namespace
Found with readability-static-definition-in-anonymous-namespace

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-02-04 15:25:31 -08:00
Rosen Penev
a3963de668 [clang-tidy] change integer prefixes to uppercase
Found with readability-uppercase-literal-suffix

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-02-04 15:20:50 -08:00
Rosen Penev
7d2c4ec775 [clang-tidy] remove unneeded return
Found with readability-redundant-control-flow

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-02-04 15:19:52 -08:00
Rosen Penev
1de5bd64d8 [clang-tidy] remove const in declaration
Found with readability-avoid-const-params-in-decls

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-02-04 15:17:10 -08:00
Rosen Penev
1923cf3844 remove redundant const qualification
Found with readability-const-return-type

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-02-04 15:16:28 -08:00
Rosen Penev
196d5fde65 Fix travis
pip is bugged on arm64 and s390x. Add --no-cache-dir to fix. For
consistency, it doesn't hurt to add everywhere.
2020-02-04 14:35:52 -08:00
Max Kellermann
140d8547c7 test/run_decoder: add option --seek 2020-02-04 22:19:21 +01:00
Max Kellermann
42eb69f46f test/meson.build: restore -Wno-missing-declarations for GTest
This is still needed for GTest 1.8.0 (Travis / Ubuntu Bionic).
2020-02-04 22:06:51 +01:00
Max Kellermann
6f579ddc95 test/DumpDecoderClient: allow overriding GetCommand() 2020-02-04 21:55:21 +01:00
Max Kellermann
8e4cb3217e lib/xiph/OggSyncState: fix offset counter by using the actual page size 2020-02-04 21:38:08 +01:00
Max Kellermann
7bcccbedad Merge remote-tracking branches 'neheb/bind', 'neheb/move' and 'neheb/str' 2020-02-04 17:03:49 +01:00
Max Kellermann
7c62887df7 tag/ApeTag: don't take reference of IterableSplitString() elements
This doesn't work because IterableSplitString() returns its elements
by value.

Fixes clang warning:

 loop variable 'i' is always a copy because the range of type 'IterableSplitString' (aka 'BasicIterableSplitString<char>') does not return a reference [-Werror,-Wrange-loop-analysis]
2020-02-04 16:53:45 +01:00
Max Kellermann
3fc859c42d Merge branch 'v0.21.x' 2020-02-04 16:49:18 +01:00
Max Kellermann
f1ad21d2bf test/meson.build: add -Wno-unused-command-line-argument for clang 9+ 2020-02-04 16:35:44 +01:00
Max Kellermann
535a099a27 test/meson.build: drop obsolete gtest warning suppressions 2020-02-04 16:32:13 +01:00
Max Kellermann
50003f6ad2 decoder/ffmpeg: add two more missing commas 2020-02-04 16:30:05 +01:00
Rosen Penev
0914644d2b add missing comma
Found with bugprone-suspicious-missing-comma

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-02-04 16:29:23 +01:00
Rosen Penev
7e41c4de58 [clang-tidy] use == instead of compare for strings
Found with readability-string-compare

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-02-02 20:11:25 -08:00
Rosen Penev
452c41b71f [clang-tidy] convert several functions to const &
Found with performance-unnecessary-value-param

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-02-02 13:21:27 -08:00
Max Kellermann
4b0444e760 Merge remote-tracking branches 'neheb/uniq', 'neheb/bool', 'neheb/loop', 'neheb/bool2', 'neheb/perf', 'neheb/void' and 'neheb/value' 2020-02-02 16:22:19 +01:00
Rosen Penev
ecad6d936a [clang-tidy] pass by value where appropriate
Found with modernize-pass-by-value

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-02-01 19:53:44 -08:00
Rosen Penev
568deefd68 [clang-tidy] remove pointless void arg
Found with modernize-redundant-void-arg

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-02-01 19:52:38 -08:00
Rosen Penev
40d0420648 [clang-tidy] convert several loops to const auto&
Found with performance-for-range-copy

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-02-01 19:49:17 -08:00
Rosen Penev
afb29942b0 [clang-tidy] simplify boolean expressions
Found with readability-simplify-boolean-expr

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-02-01 19:47:47 -08:00
Rosen Penev
15fa780c99 [clang-tidy] convert several loops to range based ones
Found with modernize-loop-convert

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-02-01 19:46:50 -08:00
Rosen Penev
9db3809c7b [clang-tidy] use bool literals where appropriate
Found with modernize-use-bool-literals

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-02-01 19:45:33 -08:00
Rosen Penev
dfed9546aa [clang-tidy] replace std::bind with lambdas
Found with modernize-avoid-bind

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-02-01 19:43:01 -08:00
Rosen Penev
469cd9582f [clang-tidy] use make_unique
Found with modernize-make-unique

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-02-01 19:40:39 -08:00
Max Kellermann
bc6eca2115 *: add explicit 2020-02-01 14:02:43 +01:00
Max Kellermann
72ec641f0d *: use auto 2020-02-01 14:02:43 +01:00
Max Kellermann
4f22f4d357 *: use nullptr instead of NULL 2020-02-01 14:02:43 +01:00
Max Kellermann
4c52001a35 *: use defaulted destructors 2020-02-01 13:47:16 +01:00
Max Kellermann
faa04966af test/test_pcm_*: use using instead of typedef 2020-02-01 13:38:55 +01:00
Max Kellermann
302eff0a59 decoder/{vorbis,mpcdec}: use using instead of typedef 2020-02-01 13:38:43 +01:00
Max Kellermann
bcc4e97c60 pcm/PcmFormat: use using instead of typedef 2020-02-01 13:38:19 +01:00
Max Kellermann
4968dd4faa pcm/Dither: use using instead of typedef 2020-02-01 13:38:00 +01:00
Max Kellermann
0896f44455 util/Domain: add noexcept 2020-02-01 13:25:57 +01:00
Max Kellermann
620872390b util/Exception: move the forwarded std::exception_ptr 2020-02-01 13:13:08 +01:00
Max Kellermann
f7c326dbeb net/StaticSocketAddress: make the cast operators constexpr 2020-02-01 11:49:55 +01:00
Max Kellermann
50de3a7886 net/AddressInfo: add MakeAddrInfo() 2020-02-01 11:48:15 +01:00
Max Kellermann
36cad54ccd util/TemplateString: remove stray semicolon 2020-02-01 11:46:06 +01:00
Max Kellermann
5ad6e7fec5 decoder/{audio,snd}file: handle MIME type "audio/wav" 2020-02-01 11:26:57 +01:00
Rosen Penev
0bb943ba3e FfmpegDecoderPlugin: add WAV support 2020-02-01 11:24:51 +01:00
Rosen Penev
b64fdae938 [clang-tidy] use override instead of virtual
Found with modernize-use-override

Signed-off-by: Rosen Penev <rosenp@gmail.com>
2020-01-31 21:27:26 -08:00
Rosen Penev
80a0cf694f MadDecoderPlugin: fix bad printf format
max_frames is size_t, not unsigned long. Fixes GCC warning.
2020-01-31 21:21:39 +01:00
Max Kellermann
0b2444450f decoder/ogg: improve seeking accuracy using binary search
On some VBR files, the single-step interpolation was very inaccurate
and inacceptable.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/720
2020-01-31 19:35:35 +01:00
Max Kellermann
faf149d08e lib/xiph/OggVisitor: add method ReadGranulepos() 2020-01-31 19:32:38 +01:00
Max Kellermann
e01bbad7bb lib/xiph/OggVisitor: update the OggStreamState offset 2020-01-31 19:24:41 +01:00
Max Kellermann
7e3eaa5921 lib/xiph/OggSyncState: keep track of the Reader offset 2020-01-31 19:24:34 +01:00
Max Kellermann
6fe4068c8e decoder/ogg: move code to SeekByte() 2020-01-31 19:24:26 +01:00
Max Kellermann
8472135859 decoder/ogg: remove unimplemented Seek() declaration 2020-01-31 19:20:52 +01:00
Max Kellermann
0c9e25b3c4 NEWS: add missing line 2020-01-25 20:09:16 +01:00
Max Kellermann
943a67c805 decoder/ogg: need to sync small files while looking for EOS
When calling OggSeekFindEOS() from inside a OggVisitor callback, then
the #InputStream may be in the middle of an Ogg packet, and the newly
initialized #ogg_sync_state will not be able to load it without the
help of ogg_sync_pageseek().  By passing "synced=false" to
OggSeekFindEOS(), we force the use of ogg_sync_pageseek() even when
not actually seeking.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/719
2020-01-25 20:07:11 +01:00
Max Kellermann
881d91f86b lib/xiph/OggFind: add parameter "synced" 2020-01-25 20:07:10 +01:00
Max Kellermann
54d57fdcc2 test/DumpDecoderClient: dump the seekable flag 2020-01-25 20:07:09 +01:00
Max Kellermann
f6f30d6d64 increment version number to 0.21.20 2020-01-25 20:06:58 +01:00
Max Kellermann
1e07d15428 output/Control: add missing nullptr check to LockRelease() 2020-01-20 17:34:38 +01:00
Max Kellermann
cc7f66822e command/partition: add command "delpartition" 2020-01-20 14:56:31 +01:00
Max Kellermann
9cbfa66886 command/partition: don't create null output in new partitions
No output at all is fine.  If the partition needs an output, it must
be moved there, but having just a null output isn't helpful.
2020-01-20 14:55:10 +01:00
Max Kellermann
4df98466df output/multiple: add "client" field, replacing the "client" parameter
By eliminating GetAnyClient(), we can have instances with no outputs
at all.
2020-01-20 14:51:08 +01:00
Max Kellermann
ff2e584bde Create FUNDING.yml 2020-01-20 14:30:52 +01:00
Max Kellermann
49309b419f Partition: add a local idle_monitor
Make idle events per-partition, but leave Instance::EmitIdle() and its
underlying idle_monitor which broadcasts idle events to all
partitions.
2020-01-20 13:33:01 +01:00
Max Kellermann
879bafb837 Instance: move OnIdle() to Instance.cxx 2020-01-20 13:32:43 +01:00
Max Kellermann
6fcea2d484 Instance: move code to OnStateModified() 2020-01-20 13:28:00 +01:00
Max Kellermann
5d597a3646 Instance: manage StateFile with std::unique_ptr 2020-01-20 13:25:19 +01:00
Max Kellermann
56eaf000a4 Partition: add client list
For efficient traversal within one partition, e.g. for distributing
partition-local idle events.
2020-01-20 13:16:13 +01:00
Max Kellermann
77271ebc1f Partition,Instance: add EmitIdle() documentation 2020-01-20 12:50:48 +01:00
Max Kellermann
fd2b2cf0bc command/message: make messages/subscriptions local to the current partition 2020-01-20 12:47:57 +01:00
Max Kellermann
438a6d7595 client/Client: make several getter methods const 2020-01-20 12:47:57 +01:00
Max Kellermann
00ed836aa9 Instance: remove partitions loop from {Found,Lost}Neighbor()
These are global events.
2020-01-20 12:18:43 +01:00
Max Kellermann
5afec8256a Main: move code to Partition::BeginShutdown() 2020-01-20 09:22:28 +01:00
Max Kellermann
f249a755e2 command/player: show partition name in "status" response 2020-01-18 23:31:39 +01:00
Max Kellermann
4029a79dc2 command/player: add local Partition reference variable 2020-01-18 23:30:45 +01:00
Max Kellermann
c16233fa74 add "moveoutput" command 2020-01-18 22:21:27 +01:00
Max Kellermann
ac126ede22 client/Client: emit idle flags in SetPartition() 2020-01-18 22:21:27 +01:00
Max Kellermann
7732db0aee output/Control: move code to method StopThread() 2020-01-18 21:46:18 +01:00
Max Kellermann
37f984ba74 output/Control: avoid sending KILL twice 2020-01-18 21:43:17 +01:00
Max Kellermann
cd612c4eef AudioFormat: move to pcm/ 2020-01-18 20:24:59 +01:00
Max Kellermann
914ad261ed pcm/meson.build: split libpcm into two
One basic library without dependencies, and one with heavy
dependencies like libsamplerate.
2020-01-18 20:08:23 +01:00
Max Kellermann
7551867249 meson.build: move Log.cxx and LogBackend.cxx into a static library
Prevents compiling those sources many times, once for each debug
program using it.
2020-01-18 19:56:16 +01:00
Max Kellermann
bdd3167495 tag/ApeLoader: remove exception handler, let caller catch 2020-01-18 19:51:46 +01:00
Max Kellermann
526c778162 tag/Id3Scan: remove exception handler, let caller catch
There's just one caller, i.e. ScanGenericTags(), which is documented
to throw exceptions.
2020-01-18 19:50:02 +01:00
Max Kellermann
e01bddbd86 output/MultipleOutputs: update API documentation 2020-01-18 19:23:49 +01:00
Max Kellermann
2817bf9e95 copyright year 2020 2020-01-18 19:23:49 +01:00
Max Kellermann
a37d22de8a pcm/Convert: choose pcm2dsd float/integer according to dest_format 2020-01-17 19:15:44 +01:00
Max Kellermann
452e1c1a6f pcm/Convert: throw if !ENABLE_DSD 2020-01-17 19:15:28 +01:00
Max Kellermann
8db86e2820 Revert "pcm/Convert: add option to enable the integer-only dsd2pcm implementation"
This reverts commit c84bae739a.  A
configuration option is not necessary, because the PcmConvert
constructor knows already whether integer or floating point is needed.
2020-01-17 19:11:10 +01:00
Max Kellermann
c84bae739a pcm/Convert: add option to enable the integer-only dsd2pcm implementation 2020-01-17 16:37:09 +01:00
Max Kellermann
925b5954c3 pcm/Dsd2Pcm: add integer-only implementation 2020-01-17 16:17:32 +01:00
Max Kellermann
dca79938d5 Merge tag 'v0.21.19'
release v0.21.19
2020-01-17 15:58:11 +01:00
Max Kellermann
4013fa15b9 release v0.21.19 2020-01-17 15:49:02 +01:00
Max Kellermann
ac1b844c15 android/AndroidManifest.xml: increase targetSdkVersion to 28
Google Play refuses uploads with a lower targetSdkVersion.
2020-01-17 15:48:43 +01:00
Max Kellermann
b8614048d4 python/build/libs.py: update Boost to 1.72.0 2020-01-17 15:33:13 +01:00
Max Kellermann
aed0d13591 python/build/libs.py: update expat to 2.2.9 2020-01-17 15:33:13 +01:00
Max Kellermann
9d02103ebe python/build/libs.py: disable various CURL features we don't use 2020-01-17 15:33:13 +01:00
Max Kellermann
61784c2144 python/build/libs.py: update CURL to 7.68.0 2020-01-17 15:19:46 +01:00
Max Kellermann
7059215795 python/build/libs.py: update FFmpeg to 4.2.2 2020-01-17 15:19:00 +01:00
Max Kellermann
2190cc7927 python/build/libs.py: update FLAC to 1.3.3 2020-01-17 15:17:21 +01:00
Max Kellermann
75dc9506c2 python/build/libs.py: update libmpdclient to 2.17 2020-01-17 15:16:20 +01:00
Max Kellermann
4f11fa0d41 config/File: allow overriding top-level settings in includes
Remove the error message and instead erase the old setting if the
"repeatable" flag is not set.

https://github.com/MusicPlayerDaemon/MPD/issues/684
2020-01-17 14:58:40 +01:00
Max Kellermann
235b6980b8 pcm/Dsd2Pcm: add optimized stereo version
This code path is 2% faster.
2020-01-14 23:38:46 +01:00
Max Kellermann
ee46150329 pcm/Dsd2Pcm: add class MultiDsd2Pcm 2020-01-14 23:29:03 +01:00
Max Kellermann
79c585bf03 pcm/PcmDsd: use size_t 2020-01-14 23:28:34 +01:00
Max Kellermann
becd81f771 pcm/PcmDsd: manage Dsd2Pcm instances, not pointers 2020-01-14 23:26:34 +01:00
Max Kellermann
2073a2c1b0 pcm/Dsd2Pcm: remove unused "lsbf" flag 2020-01-14 23:20:45 +01:00
Max Kellermann
3f3104348e pcm/Dsd2Pcm: add "restrict" attribute 2020-01-14 23:20:36 +01:00
Max Kellermann
7e80c62c7c util/GenerateArray: use double curly braces for compatibility 2020-01-14 23:16:46 +01:00
Max Kellermann
4038d8527f pcm/Dsd2Pcm: eliminate "& 0xff" 2020-01-14 22:56:28 +01:00
Max Kellermann
3565f0c8ce pcm/Dsd2Pcm: move code to TranslateSample()
10% speedup.  Strange, huh?
2020-01-14 22:51:20 +01:00
Max Kellermann
9647b2cb01 pcm/Dsd2Pcm: move code to ApplySample()
For some reason, this speeds up the library by 2%.
2020-01-14 22:43:11 +01:00
Max Kellermann
2d5bf53240 pcm/Dsd2Pcm: use sizet_t instead of int 2020-01-14 22:40:54 +01:00
Max Kellermann
a65f7b1006 pcm/Dsd2Pcm: use std::fill_n() 2020-01-14 22:39:54 +01:00
Max Kellermann
bc5b647053 pcm/Dsd2Pcm: use sizet_t instead of unsigned 2020-01-14 22:37:30 +01:00
Max Kellermann
1708ae3e3c pcm/Dsd2Pcm: use uint8_t instead of unsigned char 2020-01-14 22:36:50 +01:00
Max Kellermann
6bfbc5d320 pcm/Dsd2Pcm: move code to CalcOutputSample() 2020-01-14 22:25:54 +01:00
Max Kellermann
e7483bc5bc pcm/Dsd2Pcm: make variables more local 2020-01-14 22:21:32 +01:00
Max Kellermann
b911ec1a29 pcm/Dsd2Pcm: convert to class 2020-01-14 22:16:02 +01:00
Max Kellermann
ca2633bf26 pcm/Dsd2Pcm: remove unused function dsd2pcm_clone() 2020-01-14 22:15:05 +01:00
Max Kellermann
e0784cd48b pcm/Dsd2Pcm: make variables more local 2020-01-14 22:14:03 +01:00
Max Kellermann
566ac171f5 pcm/Dsd2Pcm: generate ctables at compile time 2020-01-14 22:11:12 +01:00
Max Kellermann
8aaf39efd6 util/GenerateArray: new utility library 2020-01-14 22:11:12 +01:00
Max Kellermann
4d95402e4e pcm/Dsd2Pcm: move formula to CalculateCtableValue() 2020-01-14 22:11:12 +01:00
Max Kellermann
4d102c4770 pcm/Dsd2Pcm: convert parameter to bool 2020-01-14 22:11:12 +01:00
Max Kellermann
91bc41ea20 pcm/Dsd2Pcm: add noexcept and remove extern 2020-01-14 22:11:12 +01:00
Max Kellermann
e565dcf18c pcm/dsd2pcm: convert to C++ 2020-01-14 22:05:58 +01:00
Max Kellermann
5a87fc7c26 pcm/dsd2pcm: remove unused sources 2020-01-14 22:05:27 +01:00
Max Kellermann
64309abc14 Merge branch 'v0.21.x' 2020-01-14 22:04:55 +01:00
Max Kellermann
ce7ec2b3f5 meson.build: add -f{function,data}-sections to C++ as well
By accident, this was only enabled for C.
2020-01-14 17:48:48 +01:00
Max Kellermann
b11c5f8d30 util/{Const,Writable}Buffer: drop more "_type" suffixes from type names 2020-01-12 14:39:54 +01:00
Max Kellermann
fada4aa529 NEWS: mention the Android build fix 2020-01-12 13:08:37 +01:00
Max Kellermann
aa0e121ade android/build.py: support x86_64 builds 2020-01-12 13:03:18 +01:00
Max Kellermann
b4700039fd android/build.py: drop -lmstackrealign
This flag doesn't appear to work, and since we never had a problem
without the flag, implementing Google's recommendation is useless.
2020-01-12 13:03:18 +01:00
Max Kellermann
ab41c16eb5 android/build.py: add -Wl,--exclude-libs=ALL
Don't export the symbols of all those static libraries.  Most
importantly, don't export the whole libc++ ABI.
2020-01-12 12:47:40 +01:00
Max Kellermann
04101f37b8 android/build.py: add -fno-faddrsig and -lmstackrealign 2020-01-12 12:41:37 +01:00
Max Kellermann
8c31370534 android/build.py: drop --sysroot, -isystem, -L, ...
These appear to be no longer necessary (tested with NDK r20b).

Closes https://github.com/android/ndk/issues/951
2020-01-12 12:11:09 +01:00
Max Kellermann
2306b0d78c android/build.py: append API level to LLVM triple
This implicitly defines __ANDROID_API__, which means we can drop the
"-D__ANDROID_API__=" parameter.

This is recommended on
https://android.googlesource.com/platform/ndk/+/ndk-release-r20/docs/BuildSystemMaintainers.md
2020-01-12 12:02:12 +01:00
Max Kellermann
cb1a9045e6 android/build.py: drop "-none" from llvm_triple
It's not mentioned on
https://developer.android.com/ndk/guides/other_build_systems
2020-01-12 11:51:20 +01:00
Max Kellermann
e92af06664 android/build.py: remove obsolete dict key android_api_level 2020-01-12 11:49:10 +01:00
Max Kellermann
af20a1c994 pulse: obey Pulse's maximum sample rate (fixes DSD128 playback)
Closes https://github.com/MusicPlayerDaemon/MPD/issues/708
2020-01-12 07:58:17 +01:00
Max Kellermann
44d7a1d8d2 pcm/Traits: drop "_type" from type names 2020-01-03 16:01:44 +01:00
Max Kellermann
4937d77cb6 util/{Const,Writable}Buffer: drop "_type" from type names
Behave like STL.
2020-01-03 15:55:06 +01:00
Max Kellermann
53f8053188 util/StringView: use using instead of typedef 2020-01-03 15:55:05 +01:00
Max Kellermann
e654c6e005 util/{Const,Writable}Buffer: use std::size_t 2020-01-03 15:55:05 +01:00
Max Kellermann
4b0e288f00 util/{Const,Writable}Buffer: add noexcept 2020-01-03 15:55:05 +01:00
Max Kellermann
71ace2fbac util/AllocatedString: use std::exchange() 2020-01-03 15:54:51 +01:00
Max Kellermann
fb450d2f41 Merge branch 'fix_cue_in_playlist' of git://github.com/maxmitti/MPD 2020-01-03 15:31:37 +01:00
Max Kellermann
84784badce Merge branch 'v0.21.x' 2020-01-03 15:31:18 +01:00
Max Kellermann
5990e46de2 lib/xiph/meson.build: exclude VorbisComments.cxx if the Vorbis decoder is disabled
Fixes a build failure.
2020-01-02 13:01:38 +01:00
Markus Mittendrein
7dea5db5df playlist/PlaylistSong: also copy start and end time in merge_song_metadata
This is needed to correctly load playlist entries that reference a song in a cuesheet that is treated as a folder.
2020-01-01 22:20:39 +01:00
Max Kellermann
756560eac3 .travis.yml: add ARM64 build (for NEON optimizations) 2020-01-01 18:36:59 +01:00
Jacob Vosmaer
dca0519336 Clang: only use [[fallthrough]] in C++ files
It appears that [[fallthrough]] is valid in C++ but not in C. And
in some Clang versions (e.g. Clang 11 on macOS), Clang is pedantic
about this and considers it an error to use [[fallthrough]] in a
.c file such as src/util/format.c.

This changes makes gcc_fallthrough a no-op under Clang in C files.
2019-12-31 13:54:09 +01:00
Max Kellermann
b9a7f30443 .travis.yml: add s390x build (big-endian) 2019-12-24 16:47:07 +01:00
Max Kellermann
32a17a997a increment version number to 0.21.19 2019-12-24 16:41:13 +01:00
Max Kellermann
803a48e96d Merge tag 'v0.21.18'
release v0.21.18
2019-12-24 16:31:06 +01:00
Max Kellermann
bf41d1ad2b release v0.21.18 2019-12-24 16:13:16 +01:00
Max Kellermann
d27e534a85 time/ISO8601: fix Windows build failure
Caused by 2bc127bb43
2019-12-24 16:12:52 +01:00
Max Kellermann
6d54928d7c Revert "lib/curl/Global: remove lower bound on timeouts"
This reverts commit 4475b8ca04.  Further
testing revealed that the threaded resolver still uses a timeout of
0ms.  This revert however lowers the bound to a minimum of 1ms instead
of 10ms.
2019-12-24 16:09:26 +01:00
Max Kellermann
0dffe05bf7 input/curl: remove unnecessary InvalidateSockets() call
Like fe598e7d30
2019-12-24 11:41:52 +01:00
Max Kellermann
9ef1f10319 .travis.yml: install brew packages using addons/homebrew 2019-12-24 11:20:54 +01:00
Max Kellermann
23fcfdbd2a .travis.yml: remove "brew update"
The packages from the Travis image are good enough, and this speeds up
the Travis build.
2019-12-24 11:20:29 +01:00
Max Kellermann
3401d26d4c .travis.yml: switch to xcode9.4, the current default 2019-12-24 10:20:04 +01:00
Max Kellermann
256753ea46 .travis.yml: disable Homebrew analytics
Don't bother sending analytics data for a CI runner.  This adds
traffic but doesn't bring anybody any benefit.
2019-12-24 10:19:25 +01:00
Max Kellermann
76cd5f8595 .travis.yml: cache Homebrew on osx 2019-12-24 10:17:37 +01:00
Max Kellermann
5684025847 .travis.yml: change "cache" yaml syntax 2019-12-24 10:17:35 +01:00
Max Kellermann
744bd1eadc time/ISO8601: refactor ParseTimeOfDay() to parse one by one
This prepares the migration away from strptime() for Windows
portability.

But the real reason I'm doing this is that strptime() on Apple is
buggy: strptime("14", "%H%M%S") (without separating colons) succeeds
even though only the hour has been parsed.  This fixes recent Travis
failures in the ParseISO8601() unit test.
2019-12-24 10:15:03 +01:00
Max Kellermann
2bc127bb43 time/ISO8601: move code to ParseTimeOfDay() 2019-12-24 10:15:01 +01:00
Max Kellermann
7770298a65 util/Compiler.h: use [[fallthrough]] on clang
Older clang versions don't support the GCC __attribute__ syntax.  For
those, don't use anything at all, and new clang versions shall use the
standard syntax.
2019-12-24 08:04:48 +01:00
Max Kellermann
fa50cdb39e .travis.yml: escape dollar signs in MATRIX_EVAL
Expand $PATH at evaluation and not at assignment, which fixes the
problem that /usr/lib/ccache was added to $PATH between the
MATRIX_EVAL assignment and its evaluation.
2019-12-24 07:51:55 +01:00
Max Kellermann
816ef12088 .travis.yml: add Ubuntu Bionic build 2019-12-23 18:12:04 +01:00
Max Kellermann
5ff786e59c .travis.yml: enable ccache on Linux 2019-12-23 18:10:58 +01:00
Max Kellermann
80fe88e8f6 .travis.yml: enable ccache on osx 2019-12-23 18:10:52 +01:00
Max Kellermann
a1afe9afc6 util/Compiler.h: add gcc_fallthrough
Works around build failures with ccache which may feed processed code
to GCC, which doesn't have the "fall through" code comments.
2019-12-23 17:53:57 +01:00
Max Kellermann
fe598e7d30 lib/curl/Global: remove InvalidateSockets() call from Remove()
curl_multi_remove_handle() calls our socket function, and there's no
need to call curl_multi_socket_action().
2019-12-23 14:52:46 +01:00
Max Kellermann
4475b8ca04 lib/curl/Global: remove lower bound on timeouts
This was a problem 9 years ago, and apparently, it has been fixed long
ago.
2019-12-23 14:50:51 +01:00
Max Kellermann
a714bdb0ce lib/curl: drop support for CURL versions older than 7.32.0
For simplicity, this commit removes a workaround for an old CURL bug.
2019-12-23 14:41:06 +01:00
Max Kellermann
087874620f test/RunCurl: new debug program 2019-12-23 14:26:56 +01:00
Max Kellermann
f1116c9258 event/Loop: remove bogus assertion
Can fail if somebody calls Break().
2019-12-23 14:20:09 +01:00
Max Kellermann
d01fb6730a storage/curl: move start call out of the constructor
This can cause request completion in the I/O thread before this
constructor returns, leaving the object in an abstract state, causing
a crash due to pure virtual method call.  We should not start the
request until this object is fully constructed.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/665
2019-12-23 13:37:58 +01:00
Max Kellermann
7bfe6a3304 test/run_storage: add command "stat" 2019-12-22 19:54:31 +01:00
Max Kellermann
57b8e7f651 Merge branch 'jv-cache-manager' of git://github.com/jacobvosmaer/MPD
Works around assertion failure in the boost::intrusive::set class
because we modified the container between insert_check() and
insert_commit().

Closes https://github.com/MusicPlayerDaemon/MPD/issues/691
2019-12-22 12:17:13 +01:00
Max Kellermann
9a577f8060 event/MultiSocketMonitor: add workaround for /dev/null
The ALSA "null" driver opens /dev/null and returns the file handle
from snd_pcm_poll_descriptors(), but /dev/null cannot be used with
epoll, the epoll_ctl() system call returns -EPERM.  This means that
the ALSA output hangs, eventually freezing the whole MPD process.

This commit adds a workaround to the MultiSocketMonitor class which is
used by the ALSA output plugin.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/695
2019-12-22 12:08:44 +01:00
Max Kellermann
d75a0d714e event/MultiSocketMonitor: remove unnecessary friend declaration 2019-12-22 12:08:44 +01:00
Max Kellermann
9be3a1554e event/MultiSocketMonitor: remove duplicate IdleMonitor::Schedule() call
SetReady() does this already.
2019-12-22 12:08:10 +01:00
Max Kellermann
7764719513 event/MultiSocketMonitor: un-inline AddSocket() 2019-12-22 12:00:12 +01:00
Max Kellermann
dcbb9fe07c event/Loop: round timeout up to avoid unnecessary wakeups 2019-12-22 11:58:31 +01:00
Max Kellermann
e3b347820a event/MultiSocketMonitor: use std::exchange() 2019-12-20 13:42:35 +01:00
Jacob Vosmaer
83acbe1002 input/cache: use simpler intrusive::set API 2019-12-18 23:15:46 +01:00
Max Kellermann
a84bf5a92e event/MultiSocketMonitor: AddSocket() returns bool 2019-12-18 17:50:21 +01:00
Max Kellermann
732bdc800d event/SocketMonitor: Schedule() returns bool 2019-12-18 17:46:33 +01:00
Max Kellermann
a8661b5931 increment version number to 0.21.18 2019-12-18 16:49:04 +01:00
Max Kellermann
a72878c5b9 io/FileDescriptor: add method FullRead() 2019-12-17 20:21:11 +01:00
Max Kellermann
bd4df1ae5d util/AllocatedArray: add WritableBuffer/ConstBuffer cast operators 2019-12-17 20:18:54 +01:00
Max Kellermann
a93b7172aa util/AllocatedArray: add ConstBuffer copy constructor 2019-12-17 20:18:49 +01:00
Max Kellermann
908b6a1939 util/AllocatedArray: use WritableBuffer::operator[] 2019-12-17 20:18:45 +01:00
Max Kellermann
561ccf600f util/AllocatedArray: remove bogus assertions
`new T[0]` must not be nullptr.
2019-12-17 20:18:39 +01:00
Max Kellermann
aee861c009 util/AllocatedArray: copy constructor copies "nulled" state 2019-12-17 20:18:34 +01:00
Max Kellermann
2cc1dd28cd util/AllocatedArray: add capacity()
For STL completeness.
2019-12-17 20:18:24 +01:00
Max Kellermann
f8d7bc1c34 util/AllocatedArray: use std::exchange() 2019-12-17 20:18:14 +01:00
Max Kellermann
a684b4fff1 lib/dbus/UDisks2: add missing <stdexcept> include 2019-12-16 23:50:01 +01:00
Max Kellermann
c82cef3aa6 lib/crypto/MD5: add missing include for uint8_t 2019-12-16 23:49:53 +01:00
Max Kellermann
683d5848f4 Merge tag 'v0.21.17'
release v0.21.17
2019-12-16 23:44:20 +01:00
Max Kellermann
5680a3a4b7 release v0.21.17 2019-12-16 23:32:44 +01:00
Max Kellermann
15ce8eb487 time/ISO8601: support omitting field separators
Closes https://github.com/MusicPlayerDaemon/MPD/issues/685
2019-12-16 23:31:29 +01:00
Max Kellermann
b7744be208 song/Filter: try ParseISO8601() first
Prepare for allowing ISO8601 time stamps without delimiters, such as
20191216, and prevent them from being interpreted as numeric UNIX time
stamps.
2019-12-16 23:31:29 +01:00
Max Kellermann
63c5d66016 time/ISO8601: support omitting minutes 2019-12-16 23:24:43 +01:00
Max Kellermann
d09bd9178f time/ISO8601: support omitting seconds 2019-12-16 23:24:43 +01:00
Max Kellermann
7d8b1860c3 time/ISO8601: support time zone offset 2019-12-16 23:24:43 +01:00
Max Kellermann
b06825829b time/ISO8601: allow omitting the "Z" suffix
And allow "Z" suffix after date.
2019-12-16 23:24:43 +01:00
Max Kellermann
ba4cd47fd8 time/ISO8601: allow omitting the time of day 2019-12-16 23:24:43 +01:00
Max Kellermann
bbe403f141 test/TestISO8601: unit test for time/ISO8601 2019-12-16 23:24:43 +01:00
Max Kellermann
5df2707d98 time/ISO8601: ParseISO8601() returns precision 2019-12-16 23:24:43 +01:00
Max Kellermann
4859ea468f time/ISO8601: implement with strptime(), without ParseTimePoint()
Prepare for adding more flexible parsing.
2019-12-16 23:24:43 +01:00
Max Kellermann
2a8830db70 time/Convert: fallback TimeGm() implementation
Move code from Parser.cxx.
2019-12-16 23:24:38 +01:00
Max Kellermann
fed9b6fd74 time/Parser: use TimeGm() 2019-12-16 23:03:31 +01:00
Max Kellermann
b02890eb8a time/Parser: explicitly initialize struct tm before strptime()
This is recommended by the strptime() manpage, because strptime() does
not initialize/set attributes which were not specified in the format
string.
2019-12-16 23:03:25 +01:00
Max Kellermann
da882a6eb6 time/Convert: include sys/time.h for struct timeval
Closes https://github.com/MusicPlayerDaemon/MPD/issues/562
2019-12-16 23:03:21 +01:00
Max Kellermann
aeb89aa9d6 time/ISO8601: forward-declare StringBuffer 2019-12-16 23:02:59 +01:00
Max Kellermann
f885807ecc time/Convert: update copyright 2019-12-16 23:02:58 +01:00
Max Kellermann
b826fd71f0 time/Convert: mention exceptions 2019-12-16 23:02:57 +01:00
Max Kellermann
ae35df1126 zeroconf/AvahiPoll: move TimevalToChrono() to time/Convert.cxx 2019-12-16 23:02:45 +01:00
Max Kellermann
80e55f6bfc time/Convert: add noexcept 2019-12-16 23:02:40 +01:00
Max Kellermann
e7411c0c4b time/Convert: add pure attributes 2019-12-16 23:02:38 +01:00
Max Kellermann
e9af692973 util/Time*: move to time/ 2019-12-16 23:02:14 +01:00
Max Kellermann
0cf90ee8b6 decoder/mad: work around bogus -Wuninitialized in GCC 10 2019-12-16 23:01:31 +01:00
Max Kellermann
dc3c0c8866 pcm/Convert, ...: add missing include for std::runtime_error 2019-12-16 22:52:50 +01:00
Max Kellermann
1c46bb1ba6 lib/gcrypt/MD5: add missing include for uint8_t 2019-12-16 22:52:22 +01:00
Max Kellermann
2e8f42c6ad util/StringBuffer: use std::size_t instead of size_t 2019-12-16 22:51:23 +01:00
Max Kellermann
b449627265 fs/io/Reader: relicense to BSD-2 2019-12-16 17:13:55 +01:00
Jacob Vosmaer
2b301ffd2c lib/xiph: add missing meson dependency 2019-12-16 17:11:14 +01:00
Jacob Vosmaer
ef0765ca10 input: add missing boost meson dependency 2019-12-16 17:11:14 +01:00
Naglis Jonaitis
9766ac6db3 Fix typo in documentation 2019-12-16 17:09:45 +01:00
Jacob Vosmaer
940206d106 filter/plugins: add missing meson dependency 2019-12-09 23:49:35 +01:00
Max Kellermann
65bbb975d2 command/fingerprint: fix inverted check 2019-12-04 16:59:01 +01:00
Max Kellermann
32799ff682 archive/zzip: improve error reporting
Most importantly, this commit translates ZZIP_ENOENT to
std::system_error(ENOENT) so IsFileNotFound() returns true and
find_stream_art() can suppress the log line.
2019-12-04 12:33:42 +01:00
Max Kellermann
ce093be12c system/Error: add FormatFileNotFound() 2019-12-04 12:33:38 +01:00
Max Kellermann
2c276770f0 util/PrintException, ...: update copyright 2019-12-04 12:33:36 +01:00
Max Kellermann
75a592f629 system/Error: move code to IsErrno() 2019-12-04 12:33:33 +01:00
Max Kellermann
c129ca9f63 lib/xiph/VorbisComments: move to separate static library
This also reverts the previous commit which was wrong.  When the
Vorbis decoder is disabled, we can't compile VorbisComments.cxx at
all.

Instead of expanding the #ifdef, this commit moves VorbisComments.cxx
to a separate library with dependencies on libvorbis (which was
missing previously, which could also lead to build failures if the
libvorbis headers were in a non-standard directory).
2019-11-20 16:12:35 +01:00
Max Kellermann
1e03457746 lib/xiph/VorbisComments: disable VorbisCommentToReplayGain() if Vorbis is disabled
Fixes build failure.
2019-11-20 15:51:49 +01:00
Max Kellermann
13ce07d181 output/shout: declare metadata as UTF-8
Apparently, Icecast defaults to ISO-8859-1 for MP3:

 http://icecast.org/docs/icecast-2.4.0/config-file.html#mountsettings

This change forces Icecast to UTF-8 without having to configure it in
Icecast's configuration file.
2019-11-06 16:05:22 +01:00
Max Kellermann
43ac264f54 tag/Mask: add noexcept 2019-11-05 10:56:20 +01:00
Max Kellermann
cbaa98c1a1 input/curl: apply the "charset" parameter to Icy-Name
Extends the URI fragment parameter added in
commit cf9ee33928

Closes https://github.com/MusicPlayerDaemon/MPD/issues/679
2019-11-04 15:44:24 +01:00
Max Kellermann
ed327c597a lib/icu/Converter: Create() returns std::unique_ptr 2019-11-04 15:44:06 +01:00
Max Kellermann
496f43e25d Merge branch 'v0.21.x' 2019-11-04 15:07:46 +01:00
Max Kellermann
d659c7df19 python/build/libs: update CURL to 7.66.0 2019-11-04 14:27:00 +01:00
Max Kellermann
f8403a1d29 python/build/libs: update FFmpeg to 4.2.1 2019-11-04 14:26:05 +01:00
Max Kellermann
ebb952c4ad neighbor/meson.build: disable if -Ddatabase=false
Fixes yet another build failure (which however only affects the 0.22
branch).

Closes https://github.com/MusicPlayerDaemon/MPD/issues/666
2019-11-04 14:18:48 +01:00
Max Kellermann
bea3b954a5 meson.build, SongUpdate: disable db-specific archive code if -Ddatabase=false
Fixes another build failure.
2019-11-04 14:15:48 +01:00
Max Kellermann
129d8e89b9 lib/sqlite: disable if -Ddatabase=false
Fixes build failure in StickerCommands.cxx.
2019-11-04 14:10:03 +01:00
Niklas Haas
65778a3774 output/Jack: mark ports as terminal
This is the correct thing to do for ports from which a signal ultimately
"originates", such as is the case with mpd.
2019-10-29 10:07:44 +01:00
kaliko
d9841668ff doc/user.rst: update build dependencies on Debian Buster 2019-10-28 15:20:05 +01:00
Max Kellermann
3f4437266b Merge branch 'buster-build-dependencies' of git://github.com/mxjeff/MPD 2019-10-28 15:19:12 +01:00
kaliko
799097c385 doc/user.rst: update build dependencies on Debian Buster 2019-10-28 15:09:14 +01:00
smutbert
4ecd4761c2 add tag "Conductor" 2019-10-25 10:12:32 +02:00
Max Kellermann
85d27cbcb9 increment version number to 0.21.17 2019-10-16 14:20:28 +02:00
Max Kellermann
e1867a99e9 Merge tag 'v0.21.16'
release v0.21.16
2019-10-16 12:03:12 +02:00
Max Kellermann
9b95e65bd9 release v0.21.16 2019-10-16 11:58:36 +02:00
Max Kellermann
12a86c4975 queue/PlaylistEdit: fix relative destination offset when moving a range
Commit 13208bf5a7 added range support to
the `move` command, but applied the wrong offset to the `to` variable.
When the source range is before the current song, and the song thus
gets decremented by the range size, then the final destination offset
must also be decremented by the range size.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/663
2019-10-15 17:00:16 +02:00
Max Kellermann
0b9435858b storage/curl: unescape file names from PROPFIND
This is the last missing piece for https://github.com/MusicPlayerDaemon/MPD/issues/662
2019-10-15 16:49:17 +02:00
Max Kellermann
f0386459ee storage/curl: follow redirects for collections without trailing slash 2019-10-15 16:42:39 +02:00
Max Kellermann
e98d4670b8 storage/curl: work around different case in hex digits 2019-10-15 16:26:53 +02:00
Max Kellermann
56cc42b752 storage/curl: use MapUTF8() to reuse existing escaping code
Commit 29f78b18b1 continued.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/662
2019-10-15 16:26:53 +02:00
Max Kellermann
ead208987d storage/curl: unescape URI in MapToRelativeUTF8() 2019-10-15 16:26:49 +02:00
Max Kellermann
364acc8949 lib/curl/Escape: add CurlUnescape() 2019-10-15 13:39:02 +02:00
Max Kellermann
a8f4d2b6fc storage/curl: move code to EscapeUriPath() 2019-10-15 13:24:06 +02:00
Max Kellermann
0eb113e7c6 lib/curl/String: OO wrapper for allocated strings returned from CURL 2019-10-15 13:13:39 +02:00
Max Kellermann
b2c4a5db14 util/UTF8: use uint8_t instead of unsigned char 2019-10-14 13:44:11 +02:00
Max Kellermann
cadfccfd0c util/UTF8: add noexcept 2019-10-14 13:41:06 +02:00
Max Kellermann
c89c7f71a2 thread/Util: lower the real-time priority from 50 to 40
On linux-rt, kernel IRQ threads are configured with priority=50, and
this change configures MPD somewhat below that priority, leaving some
room for other programs to be configured in between.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/643
2019-10-09 14:40:02 +02:00
Andre Heider
96a9670c69 lib/icu: fix build with iconv() 2019-10-07 13:34:04 +02:00
Max Kellermann
dcc5ce6792 storage/curl: request the "resourcetype" property to fix update
Without requesting the property, "good" WebDAV servers would not send
it, and so MPD could never recognize a directory, failing the database
update.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/660
2019-10-07 12:44:48 +02:00
Max Kellermann
23d08820a2 db/update/Walk: fix crash when music_directory is not a directory
Add a runtime sanity check to avoid the assertion failure.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/660
2019-10-07 12:24:25 +02:00
Max Kellermann
b9b906ab20 increment version number to 0.21.16 2019-10-07 12:24:25 +02:00
Max Kellermann
2f3e94f8d0 output/MultipleOutputs: add method IsOpen() 2019-09-26 14:52:19 +02:00
Max Kellermann
f616bfe354 output/MultipleOutputs: add method HasName() 2019-09-26 14:48:31 +02:00
Max Kellermann
f2c3d86612 output: use StringIsEqual() 2019-09-26 14:48:31 +02:00
Max Kellermann
d7dbf47a3f time/ISO8601: support omitting minutes 2019-09-25 21:39:25 +02:00
Max Kellermann
3db584a3ea curl/Easy: add SetReadFunction() 2019-09-25 21:37:42 +02:00
Max Kellermann
409002b1c3 curl/Easy: add Perform() 2019-09-25 21:37:22 +02:00
Max Kellermann
29b542fd36 curl/Easy: add SetTimeout() 2019-09-25 21:36:52 +02:00
Max Kellermann
c9590db188 util/StringView: enable string_view support only on C++17 2019-09-25 21:34:48 +02:00
Max Kellermann
0643b5abad Merge tag 'v0.21.15'
release v0.21.15
2019-09-25 21:27:31 +02:00
Max Kellermann
964804a4c2 release v0.21.15 2019-09-25 21:24:15 +02:00
Max Kellermann
92495d2b0b decoder/mpcdec: fix bogus ReplayGain values
Apparently, libmpcdec sets gain/peak variables to zero if they are not
present.  This clashes with our formula and results in bogus values
which cause noise during playback.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/640
2019-09-13 19:52:11 +02:00
Max Kellermann
9270829b5b ReplayGainInfo: move more code to a function 2019-09-13 19:50:49 +02:00
Max Kellermann
b6243a9945 decoder/mpcdec: merge duplicate code 2019-09-13 19:50:43 +02:00
Max Kellermann
496f88653d ReplayGainInfo: add static method Undefined() 2019-09-13 19:46:39 +02:00
Max Kellermann
5ef645df97 NEWS: add missing line for 818b7e0641 2019-09-08 12:54:16 +02:00
Max Kellermann
bf49c9e4e2 decoder/{dsf,dsdiff}: precalculate bit rate 2019-09-08 12:52:02 +02:00
Max Kellermann
0da9c91af2 decoder/{dsf,dsdiff}: fix displayed bit rate
The formula did not consider the channel count.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/639
2019-09-08 12:45:05 +02:00
Max Kellermann
d63e2c2641 db/update: scan CUE playlist contents
This commit adds a PlaylistPlugin attribute "as_folder" which for now
is only enabled in the "CUE" playlist plugin (which handles separate
"*.cue" files).  If a playlist with this flag set is being scanned
during database update, it will be parsed and its contents will be
added to the database.  This allows clients to inspect them like
directories and its contents will be searchable.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/39
2019-09-08 00:39:53 +02:00
Max Kellermann
5fdb804a50 db/simple/Song: add attribute "target"
Will be used for Song objects representing tracks inside a CUE file.
2019-09-08 00:32:16 +02:00
Max Kellermann
91c1274ac6 db/Song: translate relative "real_uri" paths 2019-09-08 00:31:10 +02:00
Max Kellermann
9caf90f74f util/UriRelative: add uri_apply_relative() 2019-09-08 00:07:37 +02:00
Max Kellermann
71448e645c util/UriExtract: use uri_get_scheme() in uri_has_scheme() 2019-09-08 00:06:52 +02:00
Max Kellermann
0509472636 util/UriExtract: add uri_is_relative_path() 2019-09-08 00:04:49 +02:00
Max Kellermann
0b956cf968 util/StringAPI: add memrchr() wrapper 2019-09-07 23:59:59 +02:00
Max Kellermann
2c3eb5b8ad test/TestUriRelative: new unit test 2019-09-07 23:27:24 +02:00
Max Kellermann
58363cf4dd util/UriRelative: allow "parent" to end with slash 2019-09-07 23:27:24 +02:00
Max Kellermann
2574615fa3 util/UriRelative: use StringAfterPrefix() instead of memcmp()
memcmp() can overrun the buffer.
2019-09-07 23:24:41 +02:00
Max Kellermann
15fbd2b4ab util/UriRelative: use StringIsEqual() 2019-09-07 23:22:16 +02:00
Max Kellermann
ee36a48dbb db/simple/Directory: RemoveSong() returns SongPtr 2019-09-05 21:12:10 +02:00
Max Kellermann
07f212c98c SongSave: return DetachedSong, not a std::unique_ptr<>
Eliminate unnecessary dynamic allocations.
2019-09-05 20:58:04 +02:00
Max Kellermann
a1e2602c3d SongSave: allow throwing any exception 2019-09-05 20:58:00 +02:00
Max Kellermann
b03e4ae692 queue/Save: move code to LoadQueueSong() 2019-09-05 20:56:47 +02:00
Max Kellermann
57808d1a1b queue/Save: queue_load_song() throws on error
Don't catch and log exceptions here; let the caller decide.
2019-09-05 20:55:18 +02:00
Max Kellermann
7775691965 db/simple/Song: rename "uri" to "filename"
This attribute is not a URI; it is just the filename without its
parent directory path.  To avoid confusion, let's rename it to
"filename", leaving the struct without a "uri" attribute.
2019-09-04 12:04:35 +02:00
Max Kellermann
a727150c8d db/simple/Song: remove StringView constructor 2019-09-04 12:03:56 +02:00
Max Kellermann
949916cba1 db/simple/Song: convert NewFrom() to constructor 2019-09-04 12:03:49 +02:00
Max Kellermann
497d090814 db/simple/Song: remove static method NewFile() 2019-09-04 12:03:41 +02:00
Max Kellermann
6a13847287 db/simple/Song: add template constructor 2019-09-04 12:03:37 +02:00
Max Kellermann
cbe7d052e8 db/simple/Song: use PathTraitsUTF8::Build() 2019-09-04 12:02:18 +02:00
Max Kellermann
f4d0bd8205 db/simple/Song: make "parent" a reference, not a pointer 2019-09-04 12:02:17 +02:00
Max Kellermann
1bfede120a fs/Traits: call std::string::reserve() in BuildPathImpl() 2019-09-04 12:01:25 +02:00
Max Kellermann
e96856032f SongSave: use StringIsEqual() 2019-09-04 11:13:39 +02:00
Max Kellermann
05a29e8458 db/simple/Song: simplify Export() 2019-09-03 20:36:39 +02:00
Max Kellermann
7f9a8b8748 db/simple/Song: convert "uri" to a std::string
No longer allocate it as a "VarSize".  This used to be a clever trick
to save memory 10 years ago, but these days, keeping the code
maintainable seems more important than saving a few kilobytes of
memory.
2019-09-03 20:26:47 +02:00
Max Kellermann
af3f637d3f db/simple/Song: pass StringView to constructor 2019-09-03 20:25:04 +02:00
Max Kellermann
97a9adcbec db/update/Archive: convert pointer to reference 2019-09-03 19:54:18 +02:00
Max Kellermann
177d3b0178 db/update/Archive: use MakeDirectoryIfModified() 2019-09-03 19:52:15 +02:00
Max Kellermann
12beb22c1d db/update/VirtualDirectory: add LockMakeVirtualDirectoryIfModified() 2019-09-03 19:51:20 +02:00
Max Kellermann
29fd3172ee db/update/VirtualDirectory: pass device_id to MakeVirtualDirectoryIfModified() 2019-09-03 19:49:32 +02:00
Max Kellermann
a873137702 db/update/VirtualDirectory: rename MakeDirectoryIfModified() 2019-09-03 19:49:10 +02:00
Max Kellermann
e08298a66f db/update/Container: move MakeDirectoryIfModified() to VirtualDirectory.cxx 2019-09-03 19:37:53 +02:00
Max Kellermann
fd1826cb91 db/update/Container: move SupportsContainerSuffix() to struct DecoderPlugin 2019-09-03 19:36:56 +02:00
Max Kellermann
d5681b678c db/update/Walk: move UpdatePlaylistFile() to Playlist.cxx 2019-09-03 18:53:33 +02:00
Max Kellermann
0fd6235a66 playlist/Registry: add FindPlaylistPluginBySuffix() 2019-09-02 20:28:14 +02:00
Max Kellermann
4d11745156 playlist/Plugin: add SupportsSuffix(), SupportsMimeType() 2019-09-02 20:19:47 +02:00
Max Kellermann
2038620bc4 db/simple/Directory: add method IsReallyAFile() 2019-09-02 20:15:52 +02:00
Max Kellermann
5dc7cb87bb db/simple/DirectorySave: use StringIsEqual() 2019-09-02 20:10:26 +02:00
Max Kellermann
f885e068c8 playlist/Plugin: add constructors 2019-09-01 15:01:58 +02:00
Max Kellermann
0d16772dea playlist/Plugin: rename with CamelCase 2019-09-01 14:58:49 +02:00
Max Kellermann
2376527d1f db/DatabaseSong: add noexcept 2019-09-01 14:56:27 +02:00
Max Kellermann
7f043367ed db/UniqueTags: add API documentation 2019-09-01 14:55:25 +02:00
Max Kellermann
45403b44de db/update/ExcludeList: add noexcept 2019-09-01 14:02:34 +02:00
Max Kellermann
32f865f146 db/update/InotifySource: add noexcept 2019-09-01 13:58:45 +02:00
Max Kellermann
9f92b59376 db/update/InotifyQueue: add noexcept 2019-09-01 13:58:22 +02:00
Max Kellermann
2bb5030f70 db/update/Queue: add noexcept 2019-09-01 13:55:17 +02:00
Max Kellermann
366de8773c db/update/Service: add noexcept 2019-09-01 13:51:34 +02:00
Max Kellermann
193e637dd9 python/build/libs: update Boost to 1.71.0 2019-09-01 13:03:50 +02:00
Max Kellermann
928bee933d python/build/libs: update expat to 2.2.7 2019-09-01 13:02:56 +02:00
Max Kellermann
4d1720c886 python/build/libs: update CURL to 7.65.3 2019-09-01 13:02:04 +02:00
Max Kellermann
8f8ed87327 python/build/libs: update FFmpeg to 4.2 2019-09-01 13:00:26 +02:00
Max Kellermann
28a441c977 python/build/libs: update Opus to 1.3.1 2019-09-01 12:59:17 +02:00
Max Kellermann
8cf50b08f2 python/build/libs: update libogg to 1.3.4 2019-09-01 12:58:26 +02:00
Max Kellermann
d3cc54d4eb TagArchive, db/update/Service: catch all exceptions 2019-09-01 12:57:24 +02:00
Max Kellermann
71ef0faa2c output/Source: move code to DropCurrentChunk() 2019-08-27 19:07:52 +02:00
Max Kellermann
328a6de86e output/Source: document "pending_tag" ownership 2019-08-27 19:07:52 +02:00
Max Kellermann
f750c8012a test/run_filter: use Filter::Flush() 2019-08-26 21:17:31 +02:00
Max Kellermann
b0a04b3da8 test/run_filter: pass ConstBuffer<void> to FullWrite() 2019-08-26 21:17:27 +02:00
Max Kellermann
9617bd6c85 test/run_filter: fix error message 2019-08-26 21:17:26 +02:00
Max Kellermann
4c7154bd23 filter/Observer: add noexcept 2019-08-26 21:04:35 +02:00
Max Kellermann
4f5c3b349d filter/Filter: document that Flush() can throw 2019-08-26 21:03:25 +02:00
Max Kellermann
4fabfdabde filter/Filter: allow throwing any exception 2019-08-26 21:01:22 +02:00
Max Kellermann
2e9b5e4e78 filter/Registry: rename the source file 2019-08-26 20:54:52 +02:00
Max Kellermann
115dd2b5ce lib/curl: require CURL 7.33, remove bug workaround 2019-08-26 20:43:39 +02:00
Max Kellermann
b18003ddfd lib/curl/Global: add missing include 2019-08-26 20:40:26 +02:00
Max Kellermann
6ec335dcd5 net/UniqueSocketDescriptor: import std::swap() 2019-08-26 20:37:47 +02:00
Max Kellermann
d5d6746ddf net/UniqueSocketDescriptor: update copyright year 2019-08-26 20:37:31 +02:00
Max Kellermann
00d7759cee net/SocketDescriptor: expose CheckDuplicate() 2019-08-26 20:36:51 +02:00
Max Kellermann
2ecc4e3eed net/AllocatedSocketAddress: remove config.h, we have Features.hxx already 2019-08-26 20:28:53 +02:00
Max Kellermann
7d98145ea8 net/AddressInfo: include Features.hxx instead of config.h 2019-08-26 20:26:40 +02:00
Max Kellermann
e7c5a59e39 util/Exception: support "const char *" 2019-08-26 20:24:22 +02:00
Xipmix
71c45d8ebe Typo fix 2019-08-27 00:06:39 +10:00
Max Kellermann
c9081a206a client/New: fix assertion failure in Close()
Caused by a revert accident in commit
f2cdbeace6

Closes https://github.com/MusicPlayerDaemon/MPD/issues/631
2019-08-22 14:43:53 +02:00
Max Kellermann
818b7e0641 output/solaris: include sys/stropts.h only on Solaris
This header had been available for a long time on Linux, but was
removed in glibc 2.30.  This commit moves the `#include` line inside
the `#ifdef __sun` block and adds a fake declaration of `I_FLUSH` for
the Linux build.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/630
2019-08-22 11:41:12 +02:00
Max Kellermann
e70f40fac1 increment version number to 0.21.15 2019-08-22 11:40:17 +02:00
Max Kellermann
f2cdbeace6 Revert "Client: eliminate SetExpired(), call Close() directly"
This reverts commit 58d7804d66.  It
caused a use-after-free bug when Client::OnSocketError() was called
due to a failed write, e.g. if the output buffer was full.
2019-08-22 09:52:19 +02:00
Max Kellermann
e6600b8562 Merge tag 'v0.21.14'
release v0.21.14
2019-08-21 10:52:49 +02:00
Max Kellermann
bc89ca92b4 release v0.21.14 2019-08-21 10:47:53 +02:00
Max Kellermann
b968e1b6de output/Thread: add missing return in exception handler 2019-08-21 10:20:17 +02:00
Max Kellermann
6c9f9c136b command/all: don't create new Response instance in exception handler
The new Response instance in the `catch` block didn't have the
`command` attribute set, so the error response didn't indicate which
command had failed, which however is required in the MPD protocol.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/628
2019-08-20 20:31:36 +02:00
Max Kellermann
9bff5f9e36 client/Process, command/all: add noexcept
Clarify that those can't throw, preparing for the next commit.
2019-08-20 20:28:15 +02:00
Max Kellermann
2bf26a2ff8 command/all: remove obsolete prototype 2019-08-20 20:28:10 +02:00
Max Kellermann
e33b50d9c5 command/all: simplify return from command_process() 2019-08-20 20:26:07 +02:00
Max Kellermann
21fa44c0d5 command/all: catch all exceptions 2019-08-20 20:23:54 +02:00
Max Kellermann
44444e1b89 decoder/Thread: on late SEEK, start decoder at seek position
Previously, a bogus value (whatever happened to be still in
`start_time`) was used.
2019-08-20 20:15:08 +02:00
Max Kellermann
ca450663d0 decoder/Control: work around crash after SEEK was too late
See code comment.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/629
2019-08-20 20:01:53 +02:00
Max Kellermann
04e2d08417 decoder/Control: inline WaitForDecoder() 2019-08-20 19:33:15 +02:00
Max Kellermann
af4ffa91fd decoder/Control: remove attribute client_is_waiting
This optimization is useless because sane pthread_cond_signal()
implementations check the number of waiters and do not invoke a system
call if there are none.
2019-08-20 19:23:44 +02:00
Max Kellermann
f3ed2c0a82 time/ISO8601: support omitting seconds 2019-08-19 22:44:41 +02:00
Max Kellermann
2c35ea92bd time/ISO8601: support time zone offset 2019-08-19 22:44:28 +02:00
Max Kellermann
26e0e1d25a time/ISO8601: allow omitting the "Z" suffix
And allow "Z" suffix after date.
2019-08-19 22:42:39 +02:00
Max Kellermann
6412efb6e4 time/ISO8601: allow omitting the time of day 2019-08-19 22:42:06 +02:00
Max Kellermann
995783bb2f test/TestISO8601: unit test for time/ISO8601 2019-08-19 22:41:54 +02:00
Max Kellermann
1a08bdf16f time/ISO8601: ParseISO8601() returns precision 2019-08-19 22:41:49 +02:00
Max Kellermann
48b122f2ed time/ISO8601: implement with strptime(), without ParseTimePoint()
Prepare for adding more flexible parsing.
2019-08-19 22:26:43 +02:00
Max Kellermann
06dac4783f time/Convert: fallback TimeGm() implementation
Move code from Parser.cxx.
2019-08-19 22:22:07 +02:00
Max Kellermann
fdaadc19cb time/Parser: use TimeGm() 2019-08-19 22:21:22 +02:00
Max Kellermann
2e53e9248a time/Parser: explicitly initialize struct tm before strptime()
This is recommended by the strptime() manpage, because strptime() does
not initialize/set attributes which were not specified in the format
string.
2019-08-19 22:09:38 +02:00
Max Kellermann
b7abd5691c lib/curl/Global: use auto 2019-08-19 22:00:25 +02:00
Max Kellermann
7a0957d713 lib/curl/Global: document ToRequest() 2019-08-19 22:00:06 +02:00
Max Kellermann
2934fc2507 lib/curl/Global: remove CURL* parameter from Add() and Remove() 2019-08-19 21:53:19 +02:00
Max Kellermann
0c8ff56a15 lib/curl/Easy: add constructor with URL parameter 2019-08-19 21:48:07 +02:00
Max Kellermann
07be44a50a lib/curl/Easy: add getter functions 2019-08-19 21:47:11 +02:00
Max Kellermann
7a473729af lib/curl/Easy: add method Unpause() 2019-08-19 21:46:21 +02:00
Max Kellermann
402f429b17 lib/curl/Easy: add setter functions 2019-08-19 21:38:55 +02:00
Max Kellermann
4c46ca6b59 lib/curl/Global: make ReadInfo() private 2019-08-19 21:38:09 +02:00
Max Kellermann
76a0bf68c7 lib/curl/Global: remove redundant API docs 2019-08-19 21:38:03 +02:00
Max Kellermann
9f02beaba9 lib/curl: fix coding style 2019-08-19 21:37:47 +02:00
Max Kellermann
a478af6759 util/PrintException, ...: update copyright 2019-08-19 19:11:59 +02:00
Max Kellermann
4c2434788f system/FileDescriptor: add method IsRegularFile() 2019-08-19 19:11:53 +02:00
Max Kellermann
ca9daf5e19 playlist/flac: set song URI to an empty string
Simplify the plugin by using a trivial relative URI; later,
playlist_check_translate_song() will set the correct full URI.
2019-08-16 14:55:12 +02:00
Max Kellermann
e98ce710b8 util/WStringAPI: add wcsncmp() wrapper 2019-08-16 14:48:54 +02:00
Max Kellermann
79d1004544 util/StringView: add method Compare() 2019-08-16 13:32:00 +02:00
Max Kellermann
bb7f7bd3e5 util/StringAPI: add strncmp() wrapper 2019-08-16 13:31:58 +02:00
Max Kellermann
ad2b858933 util/ForeignFifoBuffer: add friend function swap() 2019-08-16 13:27:22 +02:00
Max Kellermann
d7aa4fa7d3 util/ForeignFifoBuffer: make Swap() lower case 2019-08-16 13:27:22 +02:00
Max Kellermann
57c5603122 util/ForeignFifoBuffer: import std::swap() 2019-08-16 13:27:22 +02:00
Max Kellermann
1550113506 util/DynamicFifoBuffer: add nullptr constructor overload 2019-08-16 13:21:28 +02:00
Max Kellermann
a82d61a5e4 util/DynamicFifoBuffer: add API documentation 2019-08-16 13:21:11 +02:00
Max Kellermann
0c4a7c8004 util/AllocatedString: update copyright 2019-08-16 13:20:23 +02:00
Max Kellermann
674ee9d19a util/Exception: forward the exception in ThrowException()
Fixes -Wreturn-std-move (clang 8).
2019-08-16 13:19:34 +02:00
Max Kellermann
3344953db8 util/*FifoBuffer: use using instead of typedef 2019-08-16 13:16:45 +02:00
Max Kellermann
f909615b14 include cleanups (powered by iwyu) 2019-08-15 17:57:20 +02:00
Max Kellermann
92c89f0c86 playlist/flac: allow reading from FLAC streams 2019-08-15 11:13:39 +02:00
Max Kellermann
34246eb7fd playlist/flac: read the file only once using FLAC__Metadata_Chain 2019-08-15 10:40:48 +02:00
Max Kellermann
5894514ccb playlist/flac: move code to ToSongEnumerator() 2019-08-15 10:40:37 +02:00
Max Kellermann
dcb07e6ed4 playlist/flac: use class MemorySongEnumerator 2019-08-15 09:45:03 +02:00
Max Kellermann
ccffff9870 playlist/flac: use the NarrowPath for FLAC__metadata_get_streaminfo() 2019-08-15 09:44:20 +02:00
Max Kellermann
e34672c9d8 lib/xiph/FlacMetadataIterator: add noexcept 2019-08-14 20:14:26 +02:00
Max Kellermann
a8f314190f playlist/flac: add noexcept 2019-08-14 20:08:55 +02:00
Max Kellermann
545af857ba lib/xiph/{FlacStreamMetadata,VorbisComments}: merge redundant code 2019-08-14 19:57:12 +02:00
Max Kellermann
01f86e1c25 lib/xiph/FlacStreamMetadata: pass StringView to flac_scan_comment() 2019-08-14 19:54:19 +02:00
Max Kellermann
7a89b1656c lib/xiph/FlacStreamMetadata: properly convert entries to StringView 2019-08-14 19:44:14 +02:00
Max Kellermann
07fcf091a2 tag/MixRamp: pass StringView to ParseMixRampVorbis() 2019-08-14 19:42:48 +02:00
Max Kellermann
74a883dbf8 tag/MixRamp: add noexcept 2019-08-14 19:42:28 +02:00
Max Kellermann
5c550e8b33 lib/crypto/MD5: add option to use libavutil instead of libgcrypt 2019-08-14 18:56:10 +02:00
Max Kellermann
433e18b247 decoder/{opus,vorbis}: support embedded pictures (METADATA_BLOCK_PICTURE)
More for https://github.com/MusicPlayerDaemon/MPD/issues/42
2019-08-14 12:39:03 +02:00
Max Kellermann
2b837277c1 lib/crypto: add base64 wrapper using libavutil 2019-08-14 12:39:03 +02:00
Max Kellermann
d515a8e99a lib/gcrypt/MD5: add wrapper in lib/crypto/
Prepare for using other crypto libraries, e.g. FFmpeg's libavutil.
2019-08-14 12:39:03 +02:00
Max Kellermann
2c2efaa91f lib/xiph/VorbisComments: pass struct vorbis_comment instead of char**
Use the "comments" attribute instead of relying on the nullptr
terminator.
2019-08-14 12:28:52 +02:00
Max Kellermann
9ae9b2c18f tag/VorbisComment: use struct StringView 2019-08-14 12:22:52 +02:00
Max Kellermann
8e0d810968 tag/MixRamp: use StringView in ParseMixRampTagTemplate() 2019-08-14 12:18:49 +02:00
Max Kellermann
0f1e13d9ff util/StringView: add StartsWithIgnoreCase(), EndsWithIgnoreCase() 2019-08-14 11:36:21 +02:00
Max Kellermann
21b81dfb1d lib/gcrypt/Hash: use the "algo" parameter instead of hard-coding MD5 2019-08-13 20:02:08 +02:00
Max Kellermann
f3d16f6d1b output/Thread: fix typo in comment 2019-08-13 13:08:40 +02:00
Max Kellermann
6b51429203 decoder/opus: move comment size check to ScanOneOpusTag()
Prepare for parsing large binary comments (such as
METADATA_BLOCK_PICTURE).
2019-08-13 12:19:31 +02:00
Max Kellermann
e2da13b0d3 command/file: add command "readpicture"
Closes https://github.com/MusicPlayerDaemon/MPD/issues/42
2019-08-13 11:55:51 +02:00
Max Kellermann
54daa85ac2 decoder/flac: support embedded pictures (FLAC__METADATA_TYPE_PICTURE) 2019-08-13 11:55:51 +02:00
Max Kellermann
575ba51931 tag/Id3Scan: support embedded pictures (the "APIC" tag) 2019-08-12 20:31:43 +02:00
Max Kellermann
96a1c69c29 tag/Handler: add virtual method OnPicture()
Preparing for https://github.com/MusicPlayerDaemon/MPD/issues/42
2019-08-12 20:31:43 +02:00
Max Kellermann
3895d35a52 command/file: move code to TagScanAny() 2019-08-12 20:31:43 +02:00
Max Kellermann
b717ab0383 doc/protocol.rst: improve binary chunk description 2019-08-12 20:31:43 +02:00
Max Kellermann
4f61cd0b93 client/Response: add constant MAX_BINARY_SIZE
Use the same chunk size for all binary commands.
2019-08-12 20:23:46 +02:00
Max Kellermann
4464cdcc67 doc/protocol.rst: add missing newline to "albumart" example
This was missing in commit 0f488dcecf
2019-08-12 20:20:17 +02:00
Max Kellermann
989790e7f1 client/Response: add method WriteBinary()
Move code from read_stream_art().
2019-08-12 14:17:35 +02:00
Max Kellermann
831bc711ca decoder/mad: remove option "gapless", always do gapless
Why would anybody want to keep the silence inserted by the codec?
Other plugins/codecs (such as Vorbis) have this hard-coded as well.
2019-08-12 13:05:57 +02:00
Max Kellermann
d640961420 doc/developer.rst: add chapter about git branches 2019-08-12 12:53:22 +02:00
Max Kellermann
828c614d57 decoder/sidplay: use StringFormat<>() 2019-08-10 12:31:31 +02:00
Max Kellermann
4964ad7800 decoder/sidplay: sidplay_load_songlength_db() throws on error 2019-08-10 12:28:53 +02:00
Max Kellermann
a7976cd0f2 decoder/sidplay: automatic memory management inside struct SidplayGlobal 2019-08-10 12:26:10 +02:00
Max Kellermann
bed8a0e040 decoder/sidplay: move global variables to struct SidplayGlobal 2019-08-10 12:16:09 +02:00
Max Kellermann
b8a64771c0 decoder/sidplay: add noexcept 2019-08-10 12:12:52 +02:00
Max Kellermann
f357f743a3 pcm/Volume: use transform_n() 2019-08-10 12:05:37 +02:00
Max Kellermann
91e565d92e pcm/PcmFormat: use transform_n() 2019-08-10 12:05:35 +02:00
Max Kellermann
a189a9e478 util/TransformN: new library 2019-08-10 11:59:47 +02:00
Fredrik Noring
9654a33218 decoder/sidplay: Fix empty album names by using the SID name field
SID files are generally collections of tunes, so a SID name field makes
sense as an MPD album. The SID tune information list (STIL) has name
and title fields for individual tunes, when such are known, but MPD is
currently not using the STIL.
2019-08-10 11:01:15 +02:00
Max Kellermann
9bcd02d178 Merge branch 'v0.21.x' 2019-08-10 10:58:32 +02:00
Fredrik Noring
2d61e526de decoder/sidplay: Fix date field to have year but not company or author
Field 2 is called <released>, formerly used as <copyright>[1][2]. It is
formatted <year><space><company or author or group>, where <year> may be
<YYYY>, <YYY?>, <YY??> or <YYYY-YY>, for example "1987", "199?", "19??"
or "1985-87". The <company or author or group> may be for example Rob
Hubbard. A full field may be for example "1987 Rob Hubbard".

This change splits the <released> field at the first <space>, to retain
the <year> part.

The 51823 SID files in High Voltage SID Collection (HVSC) version 71
have the following distribution of dates:

    333 19??         11 1990-92       6 1995-99       2 2006-08
    827 198?         88 1990-93    2140 1996        530 2007
     32 1982         69 1990-94       9 1996-97      15 2007-08
      1 1982-83      49 1990-95       2 1996-98       2 2007-09
    255 1983       3467 1991          5 1996-99       1 2007-10
    677 1984         75 1991-92    1840 1997        430 2008
    775 1985         65 1991-93       4 1997-98      23 2008-09
      3 1985-86      10 1991-94    1276 1998          1 2008-12
     10 1985-87      35 1991-97       4 1998-99     631 2009
    943 1986       3320 1992        865 1999          1 2009-10
     12 1986-87      26 1992-93      24 200?        645 2010
      5 1986-89      59 1992-94     590 2000          1 2010-12
   2083 1987          1 1992-96       4 2000-01     538 2011
     31 1987-88    2996 1993        727 2001          1 2011-12
     44 1987-89      42 1993-94     875 2002        651 2012
   2510 1988         12 1993-95       2 2002-04     811 2013
    129 1988-89       2 1993-97     844 2003        790 2014
     91 1988-90    2737 1994          3 2003-05     740 2015
     58 1988-91      16 1994-95     842 2004        792 2016
   3466 1989         20 1994-96       2 2004-05     775 2017
     95 1989-90      17 1994-97     707 2005        638 2018
    150 1989-91    2271 1995          1 2005-06     284 2019
   1077 199?          2 1995-96       2 2005-07
   2834 1990          4 1995-97     785 2006
    119 1990-91       2 1995-98       6 2006-07

References:

[1] https://www.hvsc.c64.org/download/C64Music/DOCUMENTS/SID_file_format.txt
[2] https://hvsc.c64.org/info
2019-08-10 10:50:51 +02:00
Fredrik Noring
7723c481db decoder/sidplay: Fix windows-1252 to utf-8 string conversion
High Voltage SID Collection (HVSC) metadata fields are encoded in
windows-1252, as described in DOCUMENTS/SID_file_format.txt:

https://www.hvsc.c64.org/download/C64Music/DOCUMENTS/SID_file_format.txt

If utf-8 transcoding fails, or the ICU library is unavailable, fall
back to plain ASCII and replace other characters with '?'.
2019-08-10 10:45:02 +02:00
Max Kellermann
cf9ee33928 input/icy: support "charset" parameter in URI fragment
Closes https://github.com/MusicPlayerDaemon/MPD/issues/616
2019-08-10 10:07:13 +02:00
Max Kellermann
4a47bbd816 IcyMetadataParser: implement charset conversion 2019-08-10 10:07:13 +02:00
Max Kellermann
7654038d65 util/UriQueryParser: new library 2019-08-09 20:39:34 +02:00
Max Kellermann
e4612ecb66 util/UriExtract: add uri_get_fragment() 2019-08-09 20:39:23 +02:00
Max Kellermann
9c6850210d util/UriExtract: uri_get_scheme() returns StringView
Reduce overhead by not duplicating the string.
2019-08-09 20:21:37 +02:00
Max Kellermann
40a2880857 util/UriUtil: split 2019-08-09 20:21:12 +02:00
Max Kellermann
ade712d711 util/UriUtil: relicense as BSD-2 2019-08-09 20:16:02 +02:00
Max Kellermann
175e13099c doc/developer.rst: more details about error handling and OOM 2019-08-09 20:16:02 +02:00
Fredrik Noring
0ed10542cc decoder/sidplay: Fix song length initialisation during container scan
The song length was previously undetermined.
2019-08-09 15:39:36 +02:00
Max Kellermann
ab830f9afd increment version number to 0.21.14 2019-08-09 15:38:01 +02:00
Max Kellermann
349a2ea7eb Merge branch 'sid-genre-option' of git://github.com/frno7/MPD 2019-08-09 14:45:41 +02:00
Max Kellermann
192ad91010 Merge tag 'v0.21.13'
release v0.21.13
2019-08-06 11:39:25 +02:00
Max Kellermann
91fb91d89c util/StringView: prepare the transition to std::string_view
Unfortunately, we need to disable this for GCC versions older than 7,
because it doesn't have <string_view> yet.
2019-08-05 10:23:05 +02:00
Max Kellermann
8b399b7133 output/jack: use jack_free() for Windows compatibility 2019-08-05 09:35:41 +02:00
Max Kellermann
9d24f68f51 output/jack: convert to class, make attributes/methods private 2019-08-05 09:31:40 +02:00
Max Kellermann
44652fdb13 output/jack: convert callback functions to static methods 2019-08-05 09:29:27 +02:00
Max Kellermann
2892a6f5e2 output/jack: merge set_audioformat() into Open() 2019-08-05 09:28:41 +02:00
Max Kellermann
2fc40e5575 output/jack: eliminate "shutdown" flag, use only "error" (mutex protected) 2019-08-05 09:24:43 +02:00
Fredrik Noring
7363fe90bb decoder/sidplay: Add "default_genre" option
Genres are not part of the SID format, so SID files are genreless. This
"default_genre" option may be used to assign a default genre to all SID
music, for example "SID", "C64", "Chiptune", etc.
2019-08-05 06:23:40 +02:00
Max Kellermann
d146bef740 output/jack: use jack_on_info_shutdown() 2019-08-04 20:25:13 +02:00
Max Kellermann
1f4c4be1f1 output/jack: use std::atomic_bool for "shutdown" and "pause"
Without this, the compiler may optimize accesses away.
2019-08-04 20:24:51 +02:00
Max Kellermann
90067d16c0 output/jack: use SIZE_MAX instead of (size_t)-1 2019-08-04 06:34:43 +02:00
Max Kellermann
cde6c46d2f util/Macros: replace with std::size() (C++17) 2019-08-03 13:10:49 +02:00
ckdo
d305f187d5 Add the ability to specify media.role for pulse output plugin
This is useful in multiple mpd instances scenario, or multiple pulse outputs defined on the same mpd instance.
It is actually a more flexible way to route flows than the "sink" parameter, letting the PulseAudio routing do its job, but with the ability to isolate routing for each output.

If not specified, the role remains like it was before this commit, ie "music"
2019-08-03 13:03:05 +02:00
Richard Dodd
4f6a713b32 Add option to not connect jack ports automatically 2019-08-03 13:01:47 +02:00
Max Kellermann
8f981845dc switch to C++17
Time to move on, two years after 2017.
2019-08-03 12:57:56 +02:00
Max Kellermann
c764b70b3a decoder/mad: merge DecodeNextFrame() and DecodeNextFrameHeader() 2019-08-03 12:55:56 +02:00
Max Kellermann
52bb03e136 decoder/mad: eliminate redundant error handling from DecodeNextFrame()
Much of that is not possible when mad_header_decode() has already been
called.
2019-08-03 12:55:48 +02:00
Max Kellermann
a90685d6cf Merge tag 'v0.21.12'
release v0.21.12
2019-08-03 12:53:23 +02:00
Max Kellermann
fe2f8c088a Partition, ...: add noexcept to callback methods 2019-08-02 14:44:00 +02:00
Max Kellermann
af99f9fc90 pcm/Volume: convert S16 to S24 to preserve quality and reduce noise
Applying software volume to S16 samples means several bits of
precision are lost; at 25% volume, two bits are lost.  Additionally,
dithering adds some noise.

The problem gets worse when you apply the software volume code twice:
for the software mixer volume, and again for the replay gain.  This
loses some more precision and adds even more dithering noise, which
can become audible (see
https://github.com/MusicPlayerDaemon/MPD/issues/542).

By converting everything to 24 bit, we need to shift only two bits to
the right instead of ten, losing nearly no precision, and dithering is
not needed.  Even if the output device is unable to play S24 directly,
we can convert back to S16 with only one stage of dithering.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/542
2019-07-30 20:03:37 +02:00
Max Kellermann
a784c8b1ae net/Resolver: replace memset(0) with empty C++ initializer list 2019-07-29 11:32:06 +02:00
Max Kellermann
991bbea875 Merge branch 'v0.21.x' 2019-07-29 11:32:00 +02:00
Max Kellermann
a2d2210713 ls: fix early return in uri_supported_scheme()
Fixes regression by commit 4e2a551f30

Closes https://github.com/MusicPlayerDaemon/MPD/issues/599
2019-07-29 11:08:47 +02:00
Max Kellermann
426891ab31 output/Init: pass MixerType to _load_mixer() 2019-07-12 17:11:14 +02:00
Max Kellermann
b94de51ac4 system/Error: move code to IsErrno() 2019-07-12 17:11:14 +02:00
Max Kellermann
db024c27d5 output/Source: allow the ReplayGainFilter to change the AudioFormat
Just in case.
2019-07-08 20:16:53 +02:00
Max Kellermann
326c6ae615 pcm/Volume: add variable "dest_size" 2019-07-05 21:01:09 +02:00
Max Kellermann
5fa7610264 pcm/Volume: Open() returns output sample format
Prepare for a new mode which may convert to a different sample format
when applying volume, to reduce dithering.
2019-07-05 19:03:00 +02:00
Max Kellermann
1c757f8c1c pcm/Volume: allow any exception 2019-07-05 19:01:46 +02:00
Max Kellermann
06fbbe2d7b pcm/Volume: calculate PCM_VOLUME_1 2019-07-05 18:26:26 +02:00
Max Kellermann
21d91cb1d1 pcm/Volume: fix API documentation 2019-07-05 18:26:14 +02:00
Max Kellermann
9d3d4fc734 util/CharUtil: add noexcept 2019-07-05 18:05:04 +02:00
Max Kellermann
d6660bad03 util/WCharUtil: remove redundant inline keywords from constexpr functions 2019-07-05 18:03:42 +02:00
Max Kellermann
9d74b1a212 IcyMetaDataParser: include cleanup 2019-07-05 17:27:39 +02:00
Max Kellermann
54c7dc029e IcyMetaDataParser: remove useless log message 2019-07-05 17:26:31 +02:00
Max Kellermann
d8bcdca7ff IcyMetaDataParser: pass StringView to icy_add_item() 2019-07-05 17:17:44 +02:00
Max Kellermann
d663f81420 include cleanups (powered by iwyu) 2019-07-05 09:59:58 +02:00
Max Kellermann
9cdebc90a0 lib/icu/Compare: use StringIsEqualIgnoreCase() 2019-07-05 09:59:58 +02:00
Max Kellermann
0a267056d3 lib/icu/Compare: fix strcasecmp() call 2019-07-05 09:59:58 +02:00
Max Kellermann
4650a903b4 decoder/Bridge: add noexcept 2019-07-05 08:57:51 +02:00
Max Kellermann
94c9fafe16 lib/chromaprint/DecoderClient: catch and postpone InputStream::LockRead() errors 2019-07-05 08:36:14 +02:00
Max Kellermann
8480b834b3 encoder/Interface: add noexcept 2019-07-04 22:44:36 +02:00
Max Kellermann
07080574a2 encoder/Interface: allow throwing any exception 2019-07-04 22:44:11 +02:00
Max Kellermann
6c22c34300 output/oss: add noexcept 2019-07-04 22:42:19 +02:00
Max Kellermann
f54710b100 output/oss: replace enum oss_setup_result with bool
It's not a tri-state anymore since we introduced C++ exceptions.
2019-07-04 22:23:22 +02:00
Max Kellermann
196db1a8c8 output/oss: remove redundant DoClose() calls from Reopen() 2019-07-04 22:01:44 +02:00
Max Kellermann
d66ef7eac1 lib/alsa/HwSetup: don't reset dsd_mode
Fixes regression by commit 28e07e900f

Closes https://github.com/MusicPlayerDaemon/MPD/issues/596
2019-07-04 12:47:35 +02:00
Max Kellermann
0a32634d8f output/alsa: check ring buffer space before writing to it
Pass only the amount of data to PcmExport::Export() when its full
output fits into the ring buffer.  Using only a part of the
PcmExport::Export() result may cause data corruption because
PcmExport's internal state may contain partial blocks which would need
to be rolled back when only some of its output data was used.

As a side effect, this fixes an assertion failure because
PcmExport::CalcInputSize() considered partial block data and could
cause Play() to return a number larger than the "size" parameter.
2019-07-04 12:47:10 +02:00
Max Kellermann
b12fc3c60d output/alsa: throw unexpected snd_pcm_writei() errors
If snd_pcm_writei() fails, throw an error and stop playback instead
of going into an endless busy loop.
2019-07-04 12:46:18 +02:00
Max Kellermann
6d013b092f output/osx: remove trailing newline from exception messages 2019-07-03 22:21:43 +02:00
Max Kellermann
ccb182865c output/osx: fix coding style 2019-07-03 22:12:47 +02:00
Max Kellermann
412b04be58 output: allow throwing any exception 2019-07-03 22:10:26 +02:00
Max Kellermann
510e6841a0 net/AllocatedSocketAddress: import std::swap 2019-07-03 22:06:40 +02:00
Max Kellermann
2089c99348 net/{Allocated,Static}SocketAddress: use IPv[46]Address::SetPort() 2019-07-03 21:59:23 +02:00
Max Kellermann
77b5b4158c net/ToString: move UnmapV4() to class IPv6Address 2019-07-03 21:56:56 +02:00
Max Kellermann
08552f3938 net/ToString: UnmapV4() returns IPv4Address 2019-07-03 21:56:27 +02:00
Max Kellermann
2700265769 net/SocketAddress: use IPv[46]Address::Cast() 2019-07-03 21:53:42 +02:00
Max Kellermann
557098644b Merge tag 'v0.21.11'
release v0.21.11
2019-07-03 15:36:45 +02:00
Max Kellermann
44aaf51345 Merge branch 'runtime_enumeration' of git://github.com/eugene2k/MPD 2019-07-01 09:48:33 +02:00
Eugene Gorodinsky
4e2a551f30 Add runtime enumeration of supported schemas.
Fix src/ls.cxx to only print unique schemas.
Refactor src/ls.cxx to use src/input/InputPlugin functionality.

Add dynamic enumeration support to curl plugin.
2019-07-01 09:49:34 +03:00
Max Kellermann
5b01373356 output/alsa: more assertions in class PeriodBuffer 2019-06-28 09:31:51 +02:00
Max Kellermann
a92aa0bedc output/alsa: use IsCleared() instead of IsDrained() in DrainInternal()
Really drain all data from the period_buffer in any case.
2019-06-28 09:30:33 +02:00
Max Kellermann
d66f5a8590 output/alsa: replace PeriodBuffer::IsEmpty() with IsCleared()
This assertion is not about whether all data has been consumed, but
about whether there has been any data at all.
2019-06-28 09:29:18 +02:00
Max Kellermann
30ca6b8881 Merge branch 'v0.21.x' 2019-06-28 09:28:04 +02:00
Max Kellermann
cf631fca50 output/alsa: check GetFrames()>0 instead of IsEmpty() in WriteFromPeriodBuffer() 2019-06-27 21:59:43 +02:00
Max Kellermann
f0ac63d5af output/alsa: DrainInternal() ignores postponed partial frame 2019-06-27 21:23:28 +02:00
Max Kellermann
c1eb0583c4 output/alsa: add "full" assertion to WriteFromPeriodBuffer() 2019-06-27 21:22:52 +02:00
Max Kellermann
549faa8a9c output/alsa: add full check before calling FillWithSilence() 2019-06-27 21:20:38 +02:00
Max Kellermann
8f6c750064 output/alsa: improve silence generator test in DrainInternal()
There cannot be partial frames in the buffer, so we don't need
GetPeriodPosition(); it's enough to check whether head has been moved
in this period.
2019-06-27 21:17:37 +02:00
Max Kellermann
9fc1668de3 output/alsa: hold back snd_pcm_writei() until period_buffer is full
This gives MPD more control, because attempts to avoid having partial
periods in the ALSA period buffer.  For example, this means that
DrainInternal() doesn't need to generate silence to fill the partial
period.
2019-06-27 15:40:07 +02:00
Max Kellermann
e9190f4249 lib/alsa/PeriodBuffer: add missing include 2019-06-27 15:34:40 +02:00
Max Kellermann
127b464c59 lib/alsa/PeriodBuffer: add API documentation 2019-06-27 14:58:19 +02:00
Max Kellermann
048990cd2f doc/user.rst: two more heading corrections 2019-06-27 14:55:53 +02:00
Max Kellermann
01fd6e5e82 Merge branch 'v0.21.x' 2019-06-27 14:51:05 +02:00
Max Kellermann
beed004b10 pcm/Export: add GetSilence() 2019-06-26 16:04:46 +02:00
Max Kellermann
730e67d766 test/test_pcm_export: add tests for Get{In,Out}put{Frame,Block}Size() 2019-06-26 16:01:19 +02:00
Max Kellermann
34c6337887 pcm/Export: add GetInputBlockSize(), GetOutputBlockSize() 2019-06-26 15:49:08 +02:00
Max Kellermann
2093e53641 pcm/Export: add GetInputFrameSize() 2019-06-26 15:48:18 +02:00
Max Kellermann
2f243f2295 pcm/Export: rename GetFrameSize() to GetOutputFrameSize() 2019-06-26 15:46:49 +02:00
Max Kellermann
e69fd0300a pcm/Export: rename CalcSourceSize() to CalcInputSize() 2019-06-26 15:46:05 +02:00
Max Kellermann
f43cafbf7d pcm/Export: eliminate the AudioFormat parameter from GetFrameSize() 2019-06-26 15:42:47 +02:00
Max Kellermann
53faf77d20 pcm/Export: use the "channels" attribute in GetFrameSize() 2019-06-26 15:41:07 +02:00
Max Kellermann
bf574dcb0a pcm/RestBuffer: make internal methods private 2019-06-26 14:44:20 +02:00
Max Kellermann
72b8f33272 pcm/Export: split src_sample_format from alsa_channel_order
Combining these two in one single value saves some memory, but is
complicated and we may need the src_sample_format for new features
later.
2019-06-18 12:19:40 +02:00
Max Kellermann
a17f420d6b pcm/Export: update API documentation 2019-06-18 12:19:40 +02:00
Max Kellermann
f97a9ce765 Revert "MusicChunk: pad MusicChunkInfo to a multiple of 8 bytes"
This reverts commit 2c3eeb7194.  This
workaround has been obsoleted by commits
bf26adf555 and
32380d1db0
2019-06-18 11:49:52 +02:00
Max Kellermann
bf26adf555 pcm/Dsd{16,32}: stash odd frames away for the next call
Similar to commit 32380d1db0, these are
the final parts for really fixing
https://github.com/MusicPlayerDaemon/MPD/issues/469
2019-06-18 11:19:27 +02:00
Max Kellermann
0cc94fe30c pcm/Dsd{16,32}: convert public function to stateful class 2019-06-18 10:58:55 +02:00
Max Kellermann
d5d5705213 pcm/Export: update API documentation 2019-06-18 10:58:26 +02:00
Max Kellermann
96d74e77eb pcm/Dsd{16,32}: move the conversion loop to a separate function 2019-06-17 22:51:01 +02:00
Max Kellermann
ca8451cdbc tag/Type: add tag "Work"
Closes https://github.com/MusicPlayerDaemon/MPD/issues/577
2019-06-17 22:40:36 +02:00
Max Kellermann
28e07e900f pcm/Export: convert the DSD bools to an enum
These options are exclusive.
2019-06-17 22:35:00 +02:00
Max Kellermann
c75dc4a647 output/osx: remove redundant initializer 2019-06-17 22:35:00 +02:00
Max Kellermann
32380d1db0 pcm/Dop: stash odd frames away for the next call
First part of the "real" fix for
https://github.com/MusicPlayerDaemon/MPD/issues/469
2019-06-17 22:18:44 +02:00
Max Kellermann
c9f1354e4d pcm/RestBuffer: new utility class 2019-06-17 22:18:41 +02:00
Max Kellermann
e3f9e96eef pcm/Dop: convert public function to stateful class
Preparing to add more state.
2019-06-17 22:16:29 +02:00
Max Kellermann
8f9b3cbf0e pcm/Dop: add separate dsd_buffer for DSD_U16/32
The dop_buffer will be moved out soon.
2019-06-17 22:11:23 +02:00
Max Kellermann
458a1beed9 AudioFormat: move MAX_CHANNELS to pcm/ChannelDefs.hxx
Reduce header dependencies.
2019-06-17 22:11:08 +02:00
Max Kellermann
47bb1cd8b5 output/{alsa,osx}: use ConstBuffer::empty() 2019-06-17 22:09:47 +02:00
Max Kellermann
ccc96e25d3 output/{alsa,osx}: remove comment after PcmExport::Export()
Returning an empty buffer is a normal result now (since commit
79839db3a3), and doesn't deserve such a
big comment.
2019-06-17 22:09:06 +02:00
Max Kellermann
33f5e03e80 Merge branch 'v0.21.x' 2019-06-17 22:06:54 +02:00
Max Kellermann
fd7caab872 output/winmm: fix build breakage after e87f0ca771 2019-06-17 12:23:34 +02:00
Max Kellermann
e87f0ca771 pcm/Pcm*: drop more "Pcm" prefixes from source file names 2019-06-17 11:17:48 +02:00
Max Kellermann
a139279575 Copyright year 2019 2019-06-17 11:17:30 +02:00
Max Kellermann
9fcd33cc8d pcm/Dop: move the conversion loop to separate function 2019-06-16 12:23:48 +02:00
Max Kellermann
96ff6b9b8b pcm/Dop: remove redundant inline keywords 2019-06-16 12:23:38 +02:00
Max Kellermann
fd5e74dbd0 pcm/Pcm{Dop,Export}: drop "Pcm" prefix 2019-06-16 12:11:44 +02:00
Max Kellermann
b64571f4a5 pcm/Export: update API documentation 2019-06-16 11:52:57 +02:00
Max Kellermann
22a9e866bc decoder/mad: make enums strictly-typed 2019-06-16 10:02:51 +02:00
Max Kellermann
97e6ea57c4 decoder/mad: change "mp3_" suffix to "mad_" 2019-06-16 10:01:10 +02:00
Max Kellermann
527642a90b decoder/Plugin: simplify compile-time initialization
Add a `constexpr` constructor and several `constexpr` methods to
construct a DecoderPlugin at compile time, in a way which allows
adding new methods later without having to edit each plugin.
2019-06-15 14:44:37 +02:00
Max Kellermann
aebb1baad8 decoder/sidplay: remove redundant extern 2019-06-15 14:36:12 +02:00
Max Kellermann
bd6b7aa88e archive/Lookup: move to fs/LookupFile.cxx
This can be used for other purposes as well.
2019-06-15 14:26:26 +02:00
Max Kellermann
fcf6415963 archive/Lookup: pass class Path 2019-06-15 14:06:50 +02:00
Max Kellermann
be79b44dc8 archive/Lookup: pass const pointer 2019-06-15 14:04:34 +02:00
Max Kellermann
17f207ffd1 archive/Lookup: return AllocatedPath 2019-06-15 13:57:28 +02:00
Max Kellermann
476647bfa0 fs/AllocatedPath: add GetSuffix() 2019-06-15 13:57:16 +02:00
Max Kellermann
9f246fc0dc archive/Lookup: use PathTraitsFS::pointer_type 2019-06-11 19:42:16 +02:00
Max Kellermann
7de6e4dbac playlist/Registry: eliminate MIME type copy 2019-06-11 19:32:45 +02:00
Max Kellermann
15dbb8082e playlist/Registry: pass StringView to playlist_list_open_stream_mime2() 2019-06-11 19:31:22 +02:00
Max Kellermann
1a7e3bb358 util/StringUtil: add StringArrayContainsCase() overload with StringView 2019-06-11 19:29:40 +02:00
Max Kellermann
74380d2ae4 playlist/Registry: use initializer instead of memset() 2019-06-11 19:27:59 +02:00
Max Kellermann
d43ce8413a playlist/Plugin: update API documentation 2019-06-11 19:26:15 +02:00
Max Kellermann
3055c1266d output/osx: don't use variable-length arrays 2019-06-08 11:51:15 +02:00
Max Kellermann
931c3a1de0 output/osx: convert int to size_t 2019-06-08 11:49:15 +02:00
Yue Wang
a7b30fcb9e add missing header.
bad_alloc depends on <new>
2019-06-07 21:59:31 -07:00
Max Kellermann
e153407b51 tag/Id3Scan: eliminate a string copy in UFID importer 2019-06-06 13:42:14 +02:00
Max Kellermann
5675431eaf tag/ApeTag: use IterableSplitString
Eliminates yet another string copy.
2019-06-06 13:32:39 +02:00
Max Kellermann
8a136b79e5 decoder/opus: pass StringView to ScanOneOpusTag() 2019-06-06 13:27:17 +02:00
Max Kellermann
dffa25c55e decoder/opus: use StringView::Split() 2019-06-06 13:26:35 +02:00
Max Kellermann
72a0aeb265 util/NumberParser: add overload with StringView 2019-06-06 13:26:30 +02:00
Max Kellermann
e556cd20f7 util/NumberParser: add noexcept 2019-06-06 13:26:30 +02:00
Max Kellermann
80ec6f976c tag/Table: add StringView overloads 2019-06-06 13:23:16 +02:00
Max Kellermann
589639f80f tag/ParseName: add StringView overloads 2019-06-06 13:21:33 +02:00
Max Kellermann
548aa00111 tag/Handler: pass StringView to OnTag() and OnPair()
Eliminates a number of allocations, because callers don't need to copy
the strings to a newly allocated buffer only to null-terminate them.
And most callers don't need to have a null-terminated string.
2019-06-06 13:00:53 +02:00
Max Kellermann
76eb550011 util/StringView: add method Split() 2019-06-06 12:54:42 +02:00
Max Kellermann
c1719a5200 lib/xiph/FlacStreamMetadata: add missing include 2019-06-06 12:54:42 +02:00
Max Kellermann
b07bbb928a decoder/dsdiff: allow longer tag values 2019-06-06 12:44:25 +02:00
Max Kellermann
3b5a128097 decoder/dsdiff: pass DecoderClient* to dsdiff_handle_native_tag() 2019-06-06 12:43:20 +02:00
Max Kellermann
fad60f977e meson.build: enable -Wvla 2019-06-06 12:40:32 +02:00
Max Kellermann
71f9332bd3 test/TestCircularBuffer: add constexpr to fix -Wvla 2019-06-06 12:40:32 +02:00
Max Kellermann
3eae3a2826 queue/Queue: allocate MoveRange() buffer on the heap
No variable-length arrays on the stack.
2019-06-06 12:39:42 +02:00
Max Kellermann
3c1f7c77f0 queue/Queue: remove outdated API documentation 2019-06-06 12:38:21 +02:00
Max Kellermann
3e40b1d9d2 decoder/dsdiff: use a fixed-size buffer for the tag value
Variable-length arrays are a C-only feature.
2019-06-06 12:33:14 +02:00
Max Kellermann
adffbba2a5 Merge tag 'v0.21.10'
release v0.21.10
2019-06-05 22:38:54 +02:00
Max Kellermann
120e570da7 archive/Domain: remove unused library 2019-06-04 17:54:59 +02:00
Max Kellermann
0019231a37 archive/Lookup, input/Archive: remove useless log messages 2019-06-04 17:54:35 +02:00
Max Kellermann
9ae1256ae7 input/archive: include cleanup 2019-05-31 19:59:09 +02:00
Max Kellermann
e1ac377812 archive/ArchiveLookup: replace output parameters with a struct 2019-05-31 19:56:25 +02:00
Max Kellermann
7866d1a005 archive/meson.build: move ArchiveLookup.cxx to archive_glue.a
Fixes the Windows build.
2019-05-31 19:56:13 +02:00
Max Kellermann
3e3ee581a8 fs/Path: add constexpr 2019-05-31 19:47:50 +02:00
Max Kellermann
0e8ca44968 archive/List: disallow passing suffix==nullptr to archive_plugin_from_suffix() 2019-05-31 19:05:26 +02:00
Max Kellermann
12e75a523a archive/ArchiveLookup: remove "suffix" output parameter
Let the caller do this.  Our GetSuffix() function was broken anyway.
2019-05-31 19:01:22 +02:00
Max Kellermann
508ba22789 archive/ArchiveLookup: use class FileInfo 2019-05-31 18:55:27 +02:00
Max Kellermann
fa13648f2c archive/ArchiveLookup: throw on error 2019-05-31 18:52:11 +02:00
Max Kellermann
2f83ed90d0 archive/iso9660: implement seeking 2019-05-31 18:40:24 +02:00
Max Kellermann
5d74b5cee1 input/cache: first draft of the file cache 2019-05-31 17:49:52 +02:00
Max Kellermann
e8a0ce643a tag/Generic: fail if InputStream is not seekable 2019-05-31 17:49:37 +02:00
Max Kellermann
9ed4fac341 input/InputStream: check offset in Rewind()
Don't call Seek() if the stream is already at the beginning.  This
avoids unnecessary exceptions if seeking is not implemented by an
Inputstream implementation.
2019-05-31 17:47:16 +02:00
Max Kellermann
81b2b4a85c Merge branch 'v0.21.x' 2019-05-31 17:27:20 +02:00
Max Kellermann
7739b3960c mixer/Listener: add noexcept 2019-05-31 14:09:47 +02:00
Max Kellermann
11ec7117ab Partition: add noexcept 2019-05-31 14:07:33 +02:00
Max Kellermann
c3ccbfd407 queue/Playlist: add noexcept 2019-05-31 13:58:57 +02:00
Max Kellermann
de3cd96c76 queue/Playlist: remove destructor 2019-05-31 13:58:57 +02:00
Max Kellermann
d8cf7d1ef0 queue/Playlist: use C++11 initializers 2019-05-31 13:58:57 +02:00
Max Kellermann
57de2470f1 queue/Listener: add noexcept 2019-05-31 13:57:46 +02:00
Max Kellermann
8fef4af7b2 decoder/Bridge: add method OpenLocal() 2019-05-30 17:08:09 +02:00
Max Kellermann
cfb678d618 config/Parser: work around conflicting macro MAX_INPUT
linux/limits.h defines MAX_INPUT which breaks the build.
2019-05-30 16:10:01 +02:00
Max Kellermann
4eb101f046 config/Parser: add ParseSize()
Supports suffixes such as "kB" and "MB".
2019-05-29 22:44:05 +02:00
Max Kellermann
af7970337b config/Parser: get_bool() throws on error 2019-05-29 22:35:40 +02:00
Max Kellermann
96a37da03d config/Block: add method With() 2019-05-29 22:35:36 +02:00
Max Kellermann
ece35552fe config/Block: add ThrowWithNested() 2019-05-29 22:33:51 +02:00
Max Kellermann
7d599c1afc Main: add Config constructor 2019-05-29 22:22:05 +02:00
Max Kellermann
7c565bce1d Main: move two more functions down 2019-05-29 22:20:02 +02:00
Max Kellermann
d17ff18ec0 Main: move main() to the bottom 2019-05-29 22:18:06 +02:00
Max Kellermann
efc6b1b77a Main: fold mpd_main_after_fork() into MainConfigured() 2019-05-29 22:16:32 +02:00
Max Kellermann
fdbec694c6 config/Param: add method With() 2019-05-29 21:50:04 +02:00
Max Kellermann
b86d8d0cd8 config/Param: add method ThrowWithNested() 2019-05-29 21:46:27 +02:00
Max Kellermann
0b4e7b3317 client/List: use using instead of typedef 2019-05-29 21:36:27 +02:00
Max Kellermann
472e4bfd41 client/List: fold CloseAll() into destructor 2019-05-29 21:33:22 +02:00
Max Kellermann
d3d70a7eed client/List: use auto 2019-05-29 21:31:43 +02:00
Max Kellermann
39046bed85 Instance: wrap ClientList in std::unique_ptr<> 2019-05-29 21:29:55 +02:00
Max Kellermann
71a5c8b819 Main: allocate Instance on the stack 2019-05-29 21:22:25 +02:00
Max Kellermann
620a39afb4 thread/Slack: use std::chrono::duration 2019-05-29 21:11:32 +02:00
Max Kellermann
14cee01ba1 Main: simplify Android startup 2019-05-29 15:08:39 +02:00
Max Kellermann
c782fdb698 Main: use AtScopeExit() to free Android objects 2019-05-29 15:08:38 +02:00
Max Kellermann
49ba76167e Main: add overload with ConfigData parameter 2019-05-29 15:08:26 +02:00
Max Kellermann
93ab957800 Main: convert int return types to void 2019-05-29 14:52:58 +02:00
Max Kellermann
155c915733 input/buffering: make "mutex" public 2019-05-29 13:44:05 +02:00
Max Kellermann
971450f0d4 input/InputStream: make IsEOF() and IsAvailable() const 2019-05-29 13:31:54 +02:00
Max Kellermann
40a48cfba0 PluginUnavailable: add subclass PluginUnconfigured
PluginUnconfigured exceptions are logged with level "info" instead of
"error".  This suppresses some rather boring messages in the default
log level.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/565
2019-05-23 14:25:14 +02:00
Max Kellermann
9d1906da8a {event,output}/Thread: downgrade realtime scheduling errors to "info"
These messages can be confusing, but they are not critical.
2019-05-23 14:24:27 +02:00
Max Kellermann
3d2b180cf8 LogBackend: set default log level to "default"
This is the documented value, but for unknown reasons, "info" was
really the default.

This was never noticed because there are only very few "info" level
messages.
2019-05-23 14:14:58 +02:00
Max Kellermann
f987947730 Log: add Log() and LogFormat() overloads with std::exception_ptr
Make LogError()/FormatError() wrappers for those.  Now we can log
exceptions with a lower level.
2019-05-23 12:23:28 +02:00
Max Kellermann
e0d5d88104 Log: make LogLevel the first parameter
Prepare for templated functions.
2019-05-23 12:17:59 +02:00
Max Kellermann
585a745484 Log: use GetFullMessage() to print exceptions
Print all nested exceptions on a single line to avoid confusion.
2019-05-22 18:24:45 +02:00
Max Kellermann
43fe513de8 input/buffering: add API documentation 2019-05-22 12:09:20 +02:00
Max Kellermann
c1b853ca7c input/InputStream: define UNKNOWN_SIZE without undefined behavior 2019-05-22 12:01:46 +02:00
Max Kellermann
4b78038b41 input/InputStream: update API documentation 2019-05-22 12:00:16 +02:00
Max Kellermann
d651d1abfd util/SparseBuffer: move #endif to the bottom 2019-05-22 10:43:07 +02:00
Max Kellermann
5a8b734cfd tag/Id3Load: include cleanup 2019-05-22 10:23:39 +02:00
Max Kellermann
31b59a0db6 tag/Generic: allow ScanGenericTags() to throw
Propagate the error to the caller instead of logging it.
2019-05-22 10:19:28 +02:00
Max Kellermann
92f7421715 TagFile: allow ScanFileTags*() to throw 2019-05-22 10:19:27 +02:00
Max Kellermann
6f1d5105ee TagStream: allow tag_stream_scan() to throw 2019-05-22 10:19:26 +02:00
Max Kellermann
9a78371b5c DetachedSong: allow LoadFile(), Update() to throw 2019-05-22 10:19:25 +02:00
Max Kellermann
3fc4da382e db/simple/Song: allow LoadFile(), UpdateFile() to throw
Preparing to move logger calls out of lower-level libaries, and
propagating error details to the caller instead.
2019-05-22 10:19:24 +02:00
Max Kellermann
6ee7d88af0 db/update/Archive: fix inverted nullptr check
Regression by commit bbdf2dcf1e
2019-05-22 10:18:18 +02:00
Max Kellermann
bbdf2dcf1e db/simple/Song: wrap in std::unique_ptr<> 2019-05-21 22:46:34 +02:00
Max Kellermann
02bb47dd08 db/simple/Song: move struct Disposer to separate header
Allow forward-declaring it.
2019-05-21 22:42:32 +02:00
Max Kellermann
0c48b8d084 db/simple/Song: add noexcept 2019-05-21 22:41:21 +02:00
Max Kellermann
8462559b2f db/simple/Song: include cleanup 2019-05-21 22:40:08 +02:00
Max Kellermann
319c9699fb tag/Type: add TAG_GROUPING
Map ID3 "TIT1" to this new core tag type.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/563
2019-05-21 22:23:06 +02:00
Max Kellermann
06a0a4a838 time/Convert: include sys/time.h for struct timeval
Closes https://github.com/MusicPlayerDaemon/MPD/issues/562
2019-05-21 10:13:16 +02:00
Max Kellermann
8942be858b Merge tag 'v0.21.9'
release v0.21.9
2019-05-20 17:23:01 +02:00
Max Kellermann
45a091c00c .github: add issue templates 2019-05-20 16:44:02 +02:00
Max Kellermann
219546cb81 input/buffering: check error in IsAvailable() 2019-05-17 12:43:06 +02:00
Max Kellermann
555a4d738c input/buffering: pass offset to Read() and eliminate Seek()
Another step towards supporting multiple readers.
2019-05-17 12:02:55 +02:00
Max Kellermann
813567bf5c input/buffering: use notify_one() to wake up thread
There is just one thread.
2019-05-17 11:57:23 +02:00
Max Kellermann
16a07bc201 input/buffering: remove obsolete thread wakeup
The thread will always attempt to read more data since commit
2cf6b77627, so we don't need to tell it
to continue.
2019-05-17 11:56:30 +02:00
Max Kellermann
1153715608 input/buffering: rename "read_error" to "error"
The "seek_error" attribute will be eliminated soon.
2019-05-17 11:29:19 +02:00
Max Kellermann
b5c7c16fb4 input/buffering: merge multiple exception handlers into RunThread() 2019-05-17 11:23:54 +02:00
Max Kellermann
302c0515b7 input/buffering: move code to RunThreadLocked() 2019-05-17 11:21:56 +02:00
Max Kellermann
19e4672a54 input/buffering: use notify_all() instead of notify_one()
More preparations to support multiple readers.
2019-05-17 11:17:16 +02:00
Max Kellermann
c2dd6808e1 input/buffering: make read errors fatal, no recovery
If a read error occurs, it is very unlikely that the InputStream will
ever recover.  Removing the code removes some code complexity which
just isn't worth it.  And it allows supporting multiple readers for
one buffer.
2019-05-17 10:55:58 +02:00
Max Kellermann
2cf6b77627 input/buffering: eliminate "idle" flag, automatically seek to next hole 2019-05-16 22:42:29 +02:00
Max Kellermann
a5c09f4ddb input/buffering: destruct our input while mutex is unlocked 2019-05-16 22:38:37 +02:00
Max Kellermann
1acb9bcedb input/buffering: close input if buffered completely 2019-05-16 22:34:11 +02:00
Max Kellermann
0626e3d21e input/buffering: at end of input, seek to first hole 2019-05-16 22:29:10 +02:00
Max Kellermann
869d215058 input/buffering: merge "read_error" and "idle" checks in thread 2019-05-16 22:25:21 +02:00
Max Kellermann
0cf922b2da input/buffering: clear read_error after successful seek
After seeking, a new read should be done.
2019-05-16 22:24:57 +02:00
Max Kellermann
5e266cd8e4 Merge branch 'v0.21.x' 2019-05-16 22:12:48 +02:00
Max Kellermann
a199f58db5 input/buffering: update thread name 2019-05-16 22:02:51 +02:00
Max Kellermann
5277297336 input/buffered: move basic buffering code to class BufferingInputStream
Prepare to reuse it in another class.
2019-05-16 21:41:28 +02:00
Max Kellermann
604d08b2c6 Merge branch 'v0.21.x' 2019-05-16 21:26:45 +02:00
Max Kellermann
a48604d2e3 util/SparseBuffer: remove bogus noexcept from constructor
The HugeArray constructor can throw std::bad_alloc, and so can
SparseBuffer's constructor.
2019-05-08 22:34:33 +02:00
Max Kellermann
98e6a861ca util/HugeAllocator: import std::swap() 2019-05-08 22:33:41 +02:00
Max Kellermann
2c6dd04d19 util/HugeAllocator: add noexcept 2019-05-08 22:32:50 +02:00
Max Kellermann
82ca3aa281 time/ISO8601: forward-declare StringBuffer 2019-05-08 16:24:31 +02:00
Max Kellermann
b45f5c7bf6 time/Convert: update copyright 2019-05-08 16:23:58 +02:00
Max Kellermann
f54877d128 time/Convert: mention exceptions 2019-05-08 16:14:12 +02:00
Max Kellermann
af3ea97a42 zeroconf/AvahiPoll: move TimevalToChrono() to time/Convert.cxx 2019-05-08 16:11:14 +02:00
Max Kellermann
8beac03dc4 time/Convert: add noexcept 2019-05-08 16:09:27 +02:00
Max Kellermann
4a49a5587d time/Convert: add pure attributes 2019-05-08 16:08:54 +02:00
Max Kellermann
d0cfa44c8f time/FileTime: use ToUint64() in DeltaFileTimeS() 2019-05-08 16:06:19 +02:00
Max Kellermann
5bae6946c6 time/FileTime: add ToUint64(FILETIME) 2019-05-08 16:05:37 +02:00
Max Kellermann
a8fc805594 time/FileTime: drop static 2019-05-08 16:05:21 +02:00
Max Kellermann
a265738528 time/FileTime: add noexcept 2019-05-08 16:04:07 +02:00
Max Kellermann
5641c4baa6 system/Clock, fs/FileInfo: move FILETIME specific code to time/FileTime.hxx 2019-05-08 16:02:13 +02:00
Max Kellermann
96f889276f system/Clock: GetProcessUptimeS() returns std::chrono::duration 2019-05-08 15:58:01 +02:00
Max Kellermann
214ddee2f5 util/Time*: move to time/ 2019-05-08 15:47:58 +02:00
Max Kellermann
973c87b351 event/Call, ...: use wait() with predicate 2019-05-07 20:01:45 +02:00
Max Kellermann
72fc117393 thread/WindowsCond: add wait() overload with predicate 2019-05-07 19:59:32 +02:00
Max Kellermann
230ca2e968 thread/{Mutex,Cond}: use std::mutex and std::condition_variable
On Windows, we keep using our own implementations, because GCC
implements std::mutex and std::condition_variable with pthread
emulation, which is not a good choice.
2019-05-07 19:57:53 +02:00
Max Kellermann
9095167039 thread/*Cond: add wait_for() overload with predicate 2019-05-07 19:54:54 +02:00
Max Kellermann
ad4ca0c449 thread/*Cond: remove wait() overloads without std::unique_lock<> 2019-05-07 19:31:00 +02:00
Max Kellermann
0a0cc66e8f thread/Mutex: use using instead of making it a derived class
Prepare the transition to std::mutex.
2019-05-07 19:23:01 +02:00
Max Kellermann
1b5c1f75a4 input/InputStreams: pass std::unique_lock<> to various methods 2019-05-07 19:09:39 +02:00
Max Kellermann
040573c636 command/fingerprint: fix mutex locking bug
GetChromaprintCommand::DecodeStream() is called without holding the mutex.
2019-05-07 19:09:13 +02:00
Max Kellermann
bc5d4f9494 Merge branch 'v0.21.x' 2019-05-04 13:29:17 +02:00
Max Kellermann
dedc4b4b10 player/Control: pass std::unique_lock<> to Cond::wait() 2019-04-26 18:47:22 +02:00
Max Kellermann
cf348f9fae decoder/Control: pass std::unique_lock<> to Cond::wait() 2019-04-26 18:34:16 +02:00
Max Kellermann
23d56cb6a1 output/Control: pass std::unique_lock<> to Cond::wait() 2019-04-26 18:28:44 +02:00
Max Kellermann
4473816384 output/Control: add LockEnableDisableAsync() 2019-04-26 18:28:09 +02:00
Max Kellermann
2c8d004f78 output/Control: add LockWaitForCommand() 2019-04-26 18:25:36 +02:00
Max Kellermann
684bd9153e output/MultipleOutputs: simplify locking in CheckPipe()
Instead of keeping all open outputs locked, let ClearTailChunk() stall
playback until MultipleOutputs::CheckPipe() has updated the MusicPipe.
2019-04-26 18:13:14 +02:00
Max Kellermann
ec456fc57c output/MultipleOutputs: make variable more local 2019-04-26 18:13:02 +02:00
Max Kellermann
7c92eb4360 output/Control: add noexcept 2019-04-26 17:53:27 +02:00
Max Kellermann
2c6ebe28e9 playlist/EmbeddedCue:: wrap CueParser in std::unique_ptr<> 2019-04-26 14:58:09 +02:00
Max Kellermann
401f06f367 playlist/EmbeddedCue: add noexcept 2019-04-26 14:57:03 +02:00
Max Kellermann
2b4e9cc635 db/update/Service: wrap UpdateWalk in std::unique_ptr<> 2019-04-26 14:55:00 +02:00
Max Kellermann
afdaaba045 fs/io/BufferedOutputStream: add noexcept 2019-04-26 14:55:00 +02:00
Max Kellermann
1cfc0cb874 fs/io/AutoGunzipReader: use std::unique_ptr<> 2019-04-26 14:55:00 +02:00
Max Kellermann
3882c97545 fs/io/AutoGunzipReader: add noexcept 2019-04-26 14:55:00 +02:00
Max Kellermann
bf9f690c70 fs/io/GunzipReader: add noexcept 2019-04-26 14:55:00 +02:00
Max Kellermann
392b783c9e fs/io/TextFile: add noexcept 2019-04-26 14:44:27 +02:00
Max Kellermann
6d86902a02 fs/io/TextFile: use std::unique_ptr<> 2019-04-26 14:42:54 +02:00
Max Kellermann
376f4a2b16 output/MultipleOutputs: wrap AudioOutputControl in std::unique_ptr<> 2019-04-26 14:28:59 +02:00
Max Kellermann
b42f19f514 output/Control: implicitly call BeginDestroy() in destructor 2019-04-26 14:28:30 +02:00
Max Kellermann
92022658f9 thread/Cond: add wait() overload which takes a unique_lock<>
Just like std::condition_variable, which however has no way to specify
the std::mutex directly.
2019-04-26 11:51:45 +02:00
Max Kellermann
b51bae5500 thread/*Cond: rename methods to match std::condition_variable 2019-04-25 19:46:43 +02:00
Max Kellermann
5bc8cd0ecb event/Call: use std::lock_guard 2019-04-25 19:45:52 +02:00
Max Kellermann
d38a079ba1 neighbor/smbclient: use std::lock_guard 2019-04-25 19:44:59 +02:00
Max Kellermann
c75a0f7c75 neighbor/smbclient: call Run() with locked mutex 2019-04-25 19:43:45 +02:00
Max Kellermann
e740f8d969 decoder/Control: remove unused methods Lock(), Unlock() 2019-04-25 19:34:26 +02:00
Max Kellermann
9da7509944 input/curl: use class ScopeUnlock 2019-04-25 19:33:50 +02:00
Max Kellermann
36aa204575 input/smbclient: use std::lock_guard 2019-04-25 19:33:50 +02:00
Max Kellermann
2c0a968735 storage/smbclient: use std::lock_guard 2019-04-25 19:23:37 +02:00
Max Kellermann
84c406d5f5 storage/nfs: use class ScopeUnlock 2019-04-25 19:22:57 +02:00
Max Kellermann
0e48747607 event/Call: use std::lock_guard 2019-04-25 18:57:58 +02:00
Max Kellermann
f764925edc Instance: use std::unique_ptr<> to manage the NeighborGlue pointer 2019-04-25 13:09:31 +02:00
Max Kellermann
692c8025a2 Main: use AtScopeExit() to call NeighborGlue::Close() 2019-04-25 13:03:51 +02:00
Max Kellermann
a6dc1ab0a9 lib/sqlite/Database: wrapper for sqlite3* 2019-04-25 12:10:12 +02:00
Max Kellermann
77c9081f78 sticker/Database: wrap in class StickerDatabase 2019-04-25 12:05:18 +02:00
Max Kellermann
c88d5616f7 sticker/Database: move sticker_prepare() to lib/sqlite/Util.hxx 2019-04-25 11:57:29 +02:00
Max Kellermann
34d483a34a lib/sqlite/Util: move into namespace 2019-04-25 11:56:52 +02:00
Max Kellermann
5a3828ed4a sticker/*: rename source files, drop "Sticker" prefix 2019-04-24 15:15:19 +02:00
Max Kellermann
3fe7f27345 sticker/Database: eliminate sticker_foreach() 2019-04-24 15:12:58 +02:00
Max Kellermann
0dccadff89 sticker/Database: remove unused function sticker_get_value() 2019-04-24 15:09:47 +02:00
Max Kellermann
5a915eb0e6 sticker/Database: return Sticker by value 2019-04-24 15:05:05 +02:00
Max Kellermann
7b48ae4f85 sticker/Database: move struct Sticker to Sticker.hxx 2019-04-24 15:03:52 +02:00
Max Kellermann
92dc4a0ca7 sticker/Database: add noexcept 2019-04-24 15:00:24 +02:00
Max Kellermann
c7c303eec3 db/DatabaseListener: add noexcept 2019-04-24 14:57:30 +02:00
Max Kellermann
1b62adc894 Instance: add noexcept 2019-04-24 14:56:08 +02:00
Max Kellermann
0641ce79fe StateFile: add noexcept 2019-04-24 14:54:17 +02:00
Max Kellermann
b985835d8b android/Environment: add noexcept 2019-04-24 14:50:02 +02:00
Max Kellermann
e413dcf8c6 android/LogListener: add noexcept 2019-04-24 14:49:42 +02:00
Max Kellermann
ea61e6dde1 android/Context: add noexcept 2019-04-24 14:49:42 +02:00
Max Kellermann
f7f858cb07 android/Context: use DiscardException() 2019-04-24 14:44:06 +02:00
Max Kellermann
4d1546cb38 java/File: use DiscardException() 2019-04-24 14:43:09 +02:00
Max Kellermann
a4bc972aad java/File: use String::ToString() in ToAbsolutePath() 2019-04-24 14:40:31 +02:00
Max Kellermann
1415bac1d6 fs/AllocatedPath: add Android-only FromUTF8(std::string&&) overload 2019-04-24 14:39:47 +02:00
Max Kellermann
7a98a784b2 fs/Features: add macro FS_CHARSET_ALWAYS_UTF8 2019-04-24 14:28:55 +02:00
Max Kellermann
162845cc6d fs/Charset: move HAVE_FS_CHARSET to Features.hxx 2019-04-24 14:24:54 +02:00
Max Kellermann
a8ee7269bc fs/Config: add noexcept 2019-04-24 14:24:21 +02:00
Max Kellermann
7c1843ee2e fs/AllocatedPath: add noexcept 2019-04-24 14:18:24 +02:00
Max Kellermann
bc8bb41aef fs/Path: add noexcept 2019-04-24 14:17:37 +02:00
Max Kellermann
a8b94a4507 fs/Traits: add noexcept 2019-04-24 14:16:45 +02:00
Max Kellermann
f1b6deb768 java/Exception: add RethrowException() 2019-04-24 14:09:45 +02:00
Max Kellermann
72ebd5ebdd java/Object: add Object.toString() wrapper 2019-04-24 14:08:51 +02:00
Max Kellermann
61b2ae0f7c java/String: add method ToString() 2019-04-24 14:07:52 +02:00
Max Kellermann
0d2ec5ead2 java/Object: rename class Object to GlobalObject 2019-04-24 14:07:52 +02:00
Max Kellermann
5b74ed6b3b Merge tag 'v0.21.8'
release v0.21.8
2019-04-23 14:41:08 +02:00
Max Kellermann
ccc58f2a32 Merge branch 'v0.21.x' 2019-04-18 11:49:05 +02:00
Max Kellermann
d28307e082 neighbor/smbclient: fix double smbc_closedir() call
There is already one call in ReadServers(), which is the correct place
to do it.
2019-04-16 20:07:48 +02:00
Max Kellermann
aa5c5bf14f neighbor/smbclient: add noexcept 2019-04-16 20:05:14 +02:00
Max Kellermann
2e80477218 neighbor/smbclient: make Server attributes "const" 2019-04-16 20:05:11 +02:00
Max Kellermann
8b9df85daa neighbor/smbclient: remove unused attribute "alive" 2019-04-16 20:04:53 +02:00
Max Kellermann
38d0f02e83 .travis.yml: switch to another PPA for a newer ninja version
Fixes Travis failure with Meson 0.50:

 ERROR: Could not detect Ninja v1.5 or newer
2019-04-16 11:36:17 +02:00
Max Kellermann
edafe4cad6 tag/Id3Unique: add noexcept 2019-04-16 10:38:57 +02:00
Max Kellermann
3cbadf42a5 java/Ref: add move constructor 2019-04-11 11:34:52 +02:00
Max Kellermann
1d49f1108f java/Ref: allow LocalRef to be nullable
Makes using the Java glue classes simpler to use, at the cost of very
little overhead.
2019-04-11 11:32:07 +02:00
Max Kellermann
791245dec2 Merge branch 'v0.21.x' 2019-04-10 16:38:51 +02:00
Max Kellermann
8e5e97bfed command: add command "getfingerprint"
A first use case for our libchromaprint integration added by commit
30e22b753b
2019-04-05 14:23:35 +02:00
Max Kellermann
17dd334b82 client/ThreadBackgroundCommand: fix inverted check 2019-04-05 14:23:35 +02:00
Max Kellermann
ab5eb4f9ce tag/meson.build: move libchromaprint detection to lib/chromaprint/ 2019-04-05 13:51:48 +02:00
Max Kellermann
a30af2ba42 lib/chromaprint/DecoderClient: replace method PrintResult() 2019-04-05 13:40:05 +02:00
Max Kellermann
9f1c23e217 client/BackgroundCommand: infrastructure for commands running in background 2019-04-05 11:18:15 +02:00
Max Kellermann
28fc1d555f decoder/Thread: eliminate decoder_input_stream_open() 2019-04-05 10:32:07 +02:00
Max Kellermann
ac74f284aa decoder/Bridge: check for STOP before InputStream::IsReady()
If the DecoderThread gets woken up by a STOP command, this should be
detected as early as possible.
2019-04-05 10:32:06 +02:00
Max Kellermann
77af999b46 decoder/Thread: use DecoderBridge::OpenUri(), eliminate duplicate code 2019-04-05 10:29:24 +02:00
Max Kellermann
4926763f00 decoder/Bridge: call InputStream::Check() before returning 2019-04-05 10:29:20 +02:00
Max Kellermann
a19eee78c6 decoder/Bridge: make many attributes private 2019-04-05 09:26:03 +02:00
Max Kellermann
6be3c99876 decoder/Bridge: add noexcept 2019-04-05 09:04:08 +02:00
Max Kellermann
8006911a1f decoder/Client: add noexcept 2019-04-05 09:03:42 +02:00
Max Kellermann
61e5828790 input/InputStream: add noexcept to ReadTag() 2019-04-05 08:57:42 +02:00
Max Kellermann
6addc9d6e0 pcm/PcmConvert: remove unused attribute "dest_format" 2019-04-04 21:06:28 +02:00
Max Kellermann
e78d825059 pcm/PcmConvert: eliminate Open() and Close()
Let the constructor and destructor do this.  This means that all users
have to be converted to allocate PcmConvert dynamically.
2019-04-04 21:01:08 +02:00
Max Kellermann
00b04468dc filter/Convert: make in_audio_format const 2019-04-04 21:00:23 +02:00
Max Kellermann
8a07724b23 test/RunChromaprint: move class ChromaprintDecoderClient to lib/chromaprint/ 2019-04-04 20:29:27 +02:00
Max Kellermann
5256929b17 tag/Chromaprint: move to lib/chromaprint/Context.hxx 2019-04-04 20:21:10 +02:00
Max Kellermann
093bf5d859 event/*, ...: make GetEventLoop() const 2019-04-04 20:07:57 +02:00
Max Kellermann
4f6144dc71 lib/curl/Init: add const overloads 2019-04-04 20:06:43 +02:00
Max Kellermann
2d1493ed7a lib/curl/Init: add noexcept 2019-04-04 20:06:20 +02:00
Max Kellermann
43677d5740 event/MaskMonitor: add noexcept 2019-04-04 19:54:17 +02:00
Max Kellermann
693815bb32 input/AsyncInputStream: add noexcept 2019-04-04 19:54:17 +02:00
Max Kellermann
58d7804d66 Client: eliminate SetExpired(), call Close() directly 2019-04-04 10:37:38 +02:00
Max Kellermann
ea5e6d8f33 Merge branch 'v0.21.x' 2019-04-04 10:29:58 +02:00
Max Kellermann
c1272c72b0 client/Process: reset the CommandListBuilder before processing it
Allows removing a CommandResult::CLOSE check.
2019-04-03 22:38:26 +02:00
Max Kellermann
7d1db5c19f client/Process: refactor IsExpired() checks 2019-04-03 22:31:49 +02:00
Max Kellermann
2142d070a3 client/Process: refactor return statements 2019-04-03 22:30:38 +02:00
Max Kellermann
9711cee26d client/Process: update code comment 2019-04-03 22:30:18 +02:00
Max Kellermann
39baa4e364 client/Process: more strict syntax check 2019-04-03 22:29:43 +02:00
Max Kellermann
f339a53e3c client/Process: move basic syntax check to the beginning of method
This catches lines within command lists as well.
2019-04-03 22:27:41 +02:00
Max Kellermann
d9117a272b client/Response: use C++11 initializer 2019-04-03 21:53:20 +02:00
Max Kellermann
b8a8bdeaec Permission: use IterableSplitString 2019-04-03 21:47:20 +02:00
Max Kellermann
8f20edac9d Permission: pass StringView to ParsePermission()
Eliminates a temporary copy.
2019-04-03 21:45:01 +02:00
Max Kellermann
8499a662ea Permission: add noexcept 2019-04-03 21:42:31 +02:00
Max Kellermann
3f05b7d8b4 client/New: include cleanup 2019-04-03 21:41:52 +02:00
Max Kellermann
1d563700a4 client/File: include cleanup 2019-04-03 21:40:12 +02:00
Max Kellermann
def6b936c8 client/Response: add noexcept 2019-04-03 21:38:09 +02:00
Max Kellermann
3610f55479 client/Write: add noexcept 2019-04-03 21:37:38 +02:00
Max Kellermann
6db84852ae client/Listener: add noexcept 2019-04-03 21:36:02 +02:00
Max Kellermann
41dc36ba92 client/List: add noexcept 2019-04-03 21:34:53 +02:00
Max Kellermann
fe32db17d7 client/Internal: rename to Config.hxx 2019-04-03 21:31:32 +02:00
Max Kellermann
772aa4f165 client/Internal: move CLIENT_MAX_* to class Client 2019-04-03 21:28:46 +02:00
Max Kellermann
38298e0cd8 client/Internal: move client_domain to Domain.hxx 2019-04-03 21:26:16 +02:00
Max Kellermann
1213d979f8 client/*: rename source files, remove "Client" prefix 2019-04-03 20:59:00 +02:00
Max Kellermann
a9cb12b745 Client: make almost all attributes private 2019-04-03 20:16:08 +02:00
Max Kellermann
380f73c112 client/Process: convert functions to Client methods 2019-04-03 20:04:59 +02:00
Max Kellermann
9f79d034b3 client/Process: add noexcept 2019-04-03 20:04:31 +02:00
Max Kellermann
4a745a399f client: un-inline the destructor 2019-04-03 14:44:01 +02:00
Max Kellermann
c340485dd5 client: make GetEventLoop() public 2019-04-03 14:32:28 +02:00
Max Kellermann
f8570dd79f encoder/opus: use new[] instead of xalloc() 2019-04-03 14:22:32 +02:00
Max Kellermann
4a49f3cce8 doc/protocol.rst: add parameters to albumart example 2019-04-03 14:04:26 +02:00
Max Kellermann
a1ae455c69 doc/protocol.rst: make the albumart documentation more generic 2019-04-03 14:01:46 +02:00
Max Kellermann
7a1b56fe96 Merge tag 'v0.21.7'
release v0.21.7
2019-04-03 12:32:20 +02:00
Max Kellermann
508e522188 PluginUnavailable: perfect forwarding in the constructor 2019-03-29 17:17:45 +01:00
Max Kellermann
b1b630a4cc command/database: support "sort" and "window" in more commands
Closes https://github.com/MusicPlayerDaemon/MPD/issues/516
2019-03-25 19:05:49 +01:00
Max Kellermann
c60d374fc8 db/DatabasePlaylist: pass DatabaseSelection to search_add_to_playlist() 2019-03-25 19:04:34 +01:00
Max Kellermann
de4fd4c059 command/database: move code to ParseDatabaseSelection() 2019-03-25 19:02:11 +01:00
Max Kellermann
95d8b30864 protocol/Ack: add noexcept 2019-03-25 19:01:34 +01:00
Max Kellermann
eb94f409d5 protocol/Ack: perfect forwarding in the ProtocolError constructor 2019-03-25 19:01:27 +01:00
Max Kellermann
93d91936b5 test/run_filter: check for partial writes 2019-03-25 08:59:34 +01:00
Max Kellermann
2220383d83 test/run_filter: move code to WriteOrThrow() 2019-03-25 08:59:25 +01:00
Max Kellermann
3231706628 test/run_filter: use class FileDescriptor 2019-03-25 08:53:58 +01:00
Max Kellermann
ca4e53859d Merge branch 'v0.21.x' 2019-03-25 08:11:07 +01:00
Max Kellermann
61120d2059 filter/ffmpeg: use only one AVFrame
The two were never used at the same time, and merging them saves one allocation.
2019-03-24 22:29:57 +01:00
Max Kellermann
cc1822810f filter/ffmpeg: use av_buffersrc_add_frame() instead of av_buffersrc_write_frame()
This transfers ownership of the buffer instead of adding another reference.
2019-03-24 22:28:40 +01:00
Max Kellermann
a21c6884f2 filter/ffmpeg: call av_frame_unref() before av_buffersink_get_frame()
Fix another memory leak.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/514
2019-03-24 22:27:48 +01:00
Max Kellermann
2700eed08d filter/ffmpeg: remove unnecessary av_frame_make_writable() call
A newly allocated buffer doesn't need this call; it only adds overhead
for copying the data.
2019-03-24 22:26:09 +01:00
Max Kellermann
ec2badbedd filter/ffmpeg: call av_frame_unref() before av_frame_get_buffer()
av_frame_get_buffer() leaks memory if buffers were already allocated.

Fixes one of the memory leaks of https://github.com/MusicPlayerDaemon/MPD/issues/514
2019-03-24 22:24:54 +01:00
Max Kellermann
054a7557fa lib/ffmpeg/Frame: add av_frame_unref() wrapper 2019-03-24 22:21:35 +01:00
Max Kellermann
977a4570d9 Merge branch 'v0.21.x' 2019-03-21 11:49:41 +01:00
Max Kellermann
6c2077eb7c doc/plugins.rst: fix filter/ffmpeg description 2019-03-21 11:20:40 +01:00
Max Kellermann
1d436b3c86 lib/ffmpeg/IOContext: keep using avio_read() with old libavformat versions
avio_read_partial() was added in libavformat 57.81.100, and we keep
compatibility with version 57.40 for now.  Fixes regression from
commit bfb7b0117f

Closes https://github.com/MusicPlayerDaemon/MPD/issues/511
2019-03-20 13:15:05 +01:00
Max Kellermann
f86b14bfc5 tag/Chromaprint: relicense as BSD-2 2019-03-18 19:26:19 +01:00
Max Kellermann
ec5be91ff6 filter/ffmpeg: new filter plugin 2019-03-18 18:56:06 +01:00
Max Kellermann
a7a9490a0c filter/hdcd: include cleanup 2019-03-18 18:55:25 +01:00
Max Kellermann
c0d6008781 filter/hdcd: move generic code to class FfmpegFilter 2019-03-18 18:35:23 +01:00
Max Kellermann
9f62824e98 filter/hdcd: fix typo 2019-03-18 18:32:20 +01:00
Max Kellermann
b824ba3299 doc/plugins.rst: document the new "hdcd" filter plugin 2019-03-18 18:26:47 +01:00
Max Kellermann
59c4f9a089 Merge branch 'v0.21.x' 2019-03-18 18:26:23 +01:00
Max Kellermann
c673528cff filter/hdcd: new filter plugin based on FFmpeg's "af_hdcd" 2019-03-18 13:48:24 +01:00
Max Kellermann
321f01b95c filter/plugins/null: move code to src/filter/NullFilter.hxx 2019-03-18 13:48:24 +01:00
Max Kellermann
e88667e01c lib/ffmpeg/Filter: add MakeAudioBuffer{Source,Sink}() 2019-03-18 11:05:13 +01:00
Max Kellermann
fb96907b52 lib/ffmpeg/Filter: add missing include 2019-03-18 11:05:13 +01:00
Max Kellermann
09ece26200 lib/ffmpeg/SampleFormat: add ToFfmpegSampleFormat() 2019-03-18 11:02:17 +01:00
Max Kellermann
0c6d22fe47 decoder/ffmpeg: move code to lib/ffmpeg/SampleFormat.hxx 2019-03-18 10:58:46 +01:00
Max Kellermann
c563eb81a3 lib/ffmpeg/Filter: C+++ wrapper for several libavfilter objects 2019-03-18 10:32:25 +01:00
Max Kellermann
e864a0dd05 lib/ffmpeg/meson.build: detect libavfilter 2019-03-18 10:30:02 +01:00
Max Kellermann
42a05bc904 lib/ffmpeg/Frame: add more wrapper methods 2019-03-18 10:29:26 +01:00
Max Kellermann
4722175049 Merge branch 'v0.21.x' 2019-03-18 10:01:00 +01:00
Max Kellermann
3a901098e9 Merge tag 'v0.21.6'
release v0.21.6
2019-03-17 23:58:54 +01:00
Max Kellermann
a66097129d Merge branch 'v0.21.x' 2019-03-16 14:08:22 +01:00
Max Kellermann
eed4e40ec6 Merge branch 'v0.21.x' 2019-03-14 20:32:04 +01:00
Max Kellermann
6de57b36c7 song/TagSongFilter: eliminate the std::fill_n() call 2019-03-14 20:31:22 +01:00
Max Kellermann
1a0865da7a test/run_filter: ensure that partial frames will not get passed to the filter 2019-03-14 14:26:53 +01:00
Max Kellermann
a6ecf6c992 test/run_filter: move the buffer into the loop 2019-03-14 13:57:37 +01:00
Max Kellermann
cb100f2e5c input/ffmpeg: use avio_feof(), eliminate eof attribute 2019-03-13 10:41:12 +01:00
Max Kellermann
bfb7b0117f lib/ffmpeg/IOContext: allow partial reads 2019-03-13 10:39:43 +01:00
Max Kellermann
f6a705c769 input/ffmpeg: add AVIOContext wrapper class 2019-03-13 10:01:17 +01:00
Max Kellermann
0c01840a7e input/ffmpeg: use C++11 initializer 2019-03-13 09:59:45 +01:00
Max Kellermann
b0b75c54de input/ffmpeg: convert to class 2019-03-13 09:59:20 +01:00
Max Kellermann
3fc201d985 input/ffmpeg: add noexcept 2019-03-13 09:58:33 +01:00
Max Kellermann
5aa453ada3 input/ffmpeg: include cleanup 2019-03-13 09:57:50 +01:00
Max Kellermann
0009d53b3f decoder/ffmpeg: add AVCodecContext wrapper class 2019-03-13 09:41:52 +01:00
Max Kellermann
05f7a6d1ff decoder/ffmpeg: add AVFormatContext wrapper class 2019-03-13 00:27:21 +01:00
Max Kellermann
0256bbbbaf decoder/ffmpeg: wider try/catch in ffmpeg_scan_stream() 2019-03-13 00:27:21 +01:00
Max Kellermann
bce608cdbc decoder/ffmpeg: ffmpeg_decode() may throw
Don't catch and log exceptions.  Let the caller handle the error.
2019-03-13 00:20:13 +01:00
Max Kellermann
38a0844cdf decoder/ffmpeg: add AVFrame wrapper class 2019-03-12 23:51:46 +01:00
Max Kellermann
9acc6617d2 filter/registry: move extern lines to plugin headers 2019-03-12 12:26:12 +01:00
Max Kellermann
4f72f49216 filter/normalize: clean up forward declarations 2019-03-12 12:24:31 +01:00
Max Kellermann
af9840daf7 util/Clamp: remove redundant inline keywords from constexpr functions 2019-03-12 11:54:51 +01:00
Max Kellermann
a67a9c9980 tag/Pool: remove redundant inline keywords from constexpr functions 2019-03-12 11:54:44 +01:00
Max Kellermann
732b2acf35 lib/upnp: remove redundant inline keywords from constexpr functions 2019-03-12 11:54:38 +01:00
Max Kellermann
16906cdcbe fs/FileInfo: remove redundant inline keywords from constexpr functions 2019-03-12 11:54:31 +01:00
Max Kellermann
96e70659f0 lib/xiph/FlacAudioFormat: remove redundant inline keywords from constexpr functions 2019-03-12 11:53:13 +01:00
Max Kellermann
f2cacaf6b6 AudioFormat, pcm/Dsd*: remove redundant inline keywords from constexpr functions 2019-03-08 10:29:03 +01:00
Max Kellermann
24cde31328 lib/ffmpeg/Time: remove redundant inline keywords from constexpr functions 2019-03-08 10:28:02 +01:00
Max Kellermann
f6c0688684 util/ByteOrder: remove redundant inline keywords from constexpr functions 2019-03-08 10:23:14 +01:00
Max Kellermann
c176d94598 system/ByteOrder: move to util/ 2019-03-08 10:21:10 +01:00
Max Kellermann
f300ea62dc meson.build: increment version number to 0.22
Time to create a new unstable branch; stable development will now
continue in the branch v0.21.x
2019-03-07 19:10:17 +01:00
borine
c5df879cf9 decooder/plugins/PcmDecoderPlugin: add missing config for preproceesor macro definitions 2019-03-07 12:31:43 +00:00
borine
0762e5c289 decoder/plugins/PcmDecoderPlugin: guard alsa specific code with pre-processor macro test 2019-03-07 08:26:04 +00:00
borine
5d18559c1c input/plugins/AlsaInputPlugin: change default device to default and default format to 48000:16:2
using the device "default" brings this plugin into line with the AlsaOutputPlugin; and a sample rate of 48kHz is more widely used as a native default for modern hardware than 44.1kHz

Also fixes an inconsistency between the docs and code.
2019-03-06 19:37:19 +00:00
borine
62c9751ac8 doc/plugins.rst: document the ability to select the audio format when using the alsa input plugin. 2019-03-06 14:48:10 +00:00
borine
7db9c7f24e input/plugins/AlsaInputPlugin: introduce mpd.conf config block to allow user to override the builtin defaults 2019-03-06 14:18:10 +00:00
borine
c834eb4590 input/plugins/AlsaInputPlugin: extend the alsa uri parsing to permit specification of the desired pcm audio format in the uri 2019-03-06 08:53:00 +00:00
borine
945ea51bd4 decoder/plugins/PcmDecoderPlugin: introduce new internal mime type "audio/x-mpd-alsa-pcm"
This mime type is to enable the AlsaInputPlugin to communicate the pcm stream audio format to the decoder
2019-03-06 08:39:47 +00:00
1698 changed files with 46159 additions and 22415 deletions

17
.clang-format Normal file
View File

@@ -0,0 +1,17 @@
BasedOnStyle: LLVM
AccessModifierOffset: -8
AllowAllConstructorInitializersOnNextLine: false
AlwaysBreakTemplateDeclarations: Yes
BraceWrapping:
AfterFunction: true
SplitEmptyFunction: true
BreakConstructorInitializers: BeforeColon
ColumnLimit: 90
ConstructorInitializerIndentWidth: 0
ContinuationIndentWidth: 8
IndentCaseLabels: false
IndentPPDirectives: AfterHash
IndentWidth: 8
Standard: c++17
TabWidth: 8
UseTab: Always

12
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,12 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: MaxK
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

22
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,22 @@
---
name: Bug report
about: Create a bug report
---
<!-- See https://www.musicpd.org/help/ -->
## Bug report
### Describe the bug
## Expected Behavior
## Actual Behavior
## Version
<!-- Paste the output of "mpd --version" here -->
## Log
<!-- Paste relevant portions of the log file here (--verbose) -->

View File

@@ -0,0 +1,6 @@
---
name: Feature request
about: Create a feature request
---
## Feature request

9
.github/ISSUE_TEMPLATE/question.md vendored Normal file
View File

@@ -0,0 +1,9 @@
---
name: Question
about: Ask a question about MPD
---
<!-- Before you ask a question on GitHub, please read MPD's
documentation. A copy is available at
https://www.musicpd.org/doc/html/ -->
## Question

3
.gitignore vendored
View File

@@ -6,3 +6,6 @@
/output/
__pycache__/
/.clangd/
/compile_commands.json

View File

@@ -1,32 +1,43 @@
language: cpp
matrix:
jobs:
include:
# Ubuntu Focal (20.04) with GCC 9.3
- os: linux
dist: trusty
dist: focal
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- sourceline: 'ppa:mhier/libboost-latest'
- sourceline: 'ppa:mstipicevic/ninja-build-1-7-2'
- sourceline: 'ppa:deadsnakes/ppa' # for Python 3.7 (required by Meson)
packages:
- g++-6
- meson
- libgtest-dev
- boost1.67
- python3.6
- python3-urllib3
- ninja-build
before_install:
- wget https://bootstrap.pypa.io/get-pip.py
- /usr/bin/python3.6 get-pip.py --user
install:
- /usr/bin/python3.6 $HOME/.local/bin/pip install --user meson
env:
# use gold as workaround for https://sourceware.org/bugzilla/show_bug.cgi?id=17068
- MATRIX_EVAL="export CC=gcc-6 CXX=g++-6 LDFLAGS=-fuse-ld=gold PATH=$HOME/.local/bin:$PATH"
- libboost-dev
- libfmt-dev
# Ubuntu Focal (20.04) with GCC 9.3 on big-endian
- os: linux
arch: s390x
dist: focal
addons:
apt:
packages:
- meson
- libgtest-dev
- libboost-dev
- libfmt-dev
# Ubuntu Focal (20.04) with GCC 9.3 on ARM64
- os: linux
arch: arm64
dist: focal
addons:
apt:
packages:
- meson
- libgtest-dev
- libboost-dev
- libfmt-dev
# Ubuntu Trusty (16.04) with GCC 8
- os: linux
dist: trusty
addons:
@@ -34,7 +45,7 @@ matrix:
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
@@ -45,31 +56,55 @@ matrix:
- ninja-build
before_install:
- wget https://bootstrap.pypa.io/get-pip.py
- /usr/bin/python3.6 get-pip.py --user
- /usr/bin/python3.6 get-pip.py --user --no-cache-dir
install:
- /usr/bin/python3.6 $HOME/.local/bin/pip install --user meson
- /usr/bin/python3.6 $HOME/.local/bin/pip install --user meson --no-cache-dir
env:
# use gold as workaround for https://sourceware.org/bugzilla/show_bug.cgi?id=17068
- MATRIX_EVAL="export CC=gcc-8 CXX=g++-8 LDFLAGS=-fuse-ld=gold PATH=$HOME/.local/bin:$PATH"
- MATRIX_EVAL="export CC='ccache gcc-8' CXX='ccache g++-8' LDFLAGS=-fuse-ld=gold PATH=\$HOME/.local/bin:\$PATH"
- os: osx
osx_image: xcode9.3beta
osx_image: xcode11.6
addons:
homebrew:
packages:
- ccache
- meson
- fmt
- googletest
- icu4c
- ffmpeg
- libnfs
- yajl
- libupnp
- libid3tag
- chromaprint
- libsamplerate
- libsoxr
# libzzip appears to be broken on Homebrew: "ld: library not found for -lzzip"
#- libzzip
- flac
- opus
- libvorbis
- faad2
- wavpack
- libmpdclient
env:
- MATRIX_EVAL=""
- MATRIX_EVAL="export PATH=/usr/local/opt/ccache/libexec:$PATH HOMEBREW_NO_ANALYTICS=1"
cache:
- apt
- ccache
apt: true
ccache: true
directories:
- $HOME/Library/Caches/Homebrew
before_cache:
- test "$TRAVIS_OS_NAME" != "osx" || brew cleanup
before_install:
- eval "${MATRIX_EVAL}"
# C++14
- test "$TRAVIS_OS_NAME" != "osx" || brew update
install:
# C++14
- test "$TRAVIS_OS_NAME" != "osx" || brew install ccache meson
- test "$TRAVIS_OS_NAME" != "osx" || brew install --HEAD https://gist.githubusercontent.com/Kronuz/96ac10fbd8472eb1e7566d740c4034f8/raw/gtest.rb
before_script:
- ccache -s

View File

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

411
NEWS
View File

@@ -1,3 +1,414 @@
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
"window" parameters
- add command "readpicture" to download embedded pictures
- command "moveoutput" moves an output between partitions
- command "delpartition" deletes a partition
- show partition name in "status" response
* tags
- new tags "Grouping" (for ID3 "TIT1"), "Work" and "Conductor"
* input
- curl: support "charset" parameter in URI fragment
- ffmpeg: allow partial reads
- io_uring: new plugin for local files on Linux (using liburing)
- smbclient: close unused SMB/CIFS connections
* database
- upnp: drop support for libupnp versions older than 1.8
* playlist
- cue: integrate contents in database
* decoder
- ffmpeg: support RTSP
- mad: remove option "gapless", always do gapless
- sidplay: add option "default_genre"
- sidplay: map SID name field to "Album" tag
- sidplay: add support for new song length format with libsidplayfp 2.0
- vorbis, opus: improve seeking accuracy
* playlist
- flac: support reading CUE sheets from remote FLAC files
* filter
- ffmpeg: new plugin based on FFmpeg's libavfilter library
- hdcd: new plugin based on FFmpeg's "af_hdcd" for HDCD playback
- volume: convert S16 to S24 to preserve quality and reduce dithering noise
- dsd: add integer-only DSD to PCM converter
* output
- jack: add option "auto_destination_ports"
- jack: report error details
- pulse: add option "media_role"
- solaris: support S8 and S32
* lower the real-time priority from 50 to 40
* switch to C++17
- GCC 8 or clang 5 (or newer) recommended
ver 0.21.26 (2020/09/21)
* database
- inotify: obey ".mpdignore" files
* output
- osx: fix crash bug
- sles: support floating point samples
* archive
- bzip2: fix crash on corrupt bzip2 file
- bzip2: flush output at end of input file
- iso9660: fix unaligned reads
- iso9660: support seeking
- zzip: fix crash on corrupt ZIP file
* decoder
- ffmpeg: remove "rtsp://" from the list of supported protocols
- ffmpeg: add "hls+http://" to the list of supported protocols
- opus: support the gain value from the Opus header
- sndfile: fix lost samples at end of file
* fix "single" mode bug after resuming playback
* the default log_level is "default", not "info"
ver 0.21.25 (2020/07/06)
* protocol:
- fix crash when using "rangeid" while playing
* database
- simple: automatically scan new mounts
- upnp: fix compatibility with Plex DLNA
* storage
- fix disappearing mounts after mounting twice
- udisks: fix reading ".mpdignore"
* input
- file: detect premature end of file
- smbclient: don't send credentials to MPD clients
* decoder
- opus: apply pre-skip and end trimming
- opus: fix memory leak
- opus: fix crash bug
- vorbis: fix crash bug
* output
- osx: improve sample rate selection
- osx: fix noise while stopping
* neighbor
- upnp: fix crash during shutdown
* Windows/Android:
- fix Boost detection after breaking change in Meson 0.54
ver 0.21.24 (2020/06/10)
* protocol
- "tagtypes" requires no permissions
* database
- simple: fix crash when mounting twice
* decoder
- modplug: fix Windows build failure
- wildmidi: attempt to detect WildMidi using pkg-config
- wildmidi: fix Windows build failure
* player
- don't restart current song if seeking beyond end
* Android
- enable the decoder plugins GME, ModPlug and WildMidi
- fix build failure with Android NDK r21
* Windows
- fix stream playback
- enable the decoder plugins GME, ModPlug and WildMidi
- work around Meson bug breaking the Windows build with GCC 10
* fix unit test failure
ver 0.21.23 (2020/04/23)
* protocol
- add tag fallback for AlbumSort
* storage
- curl: fix corrupt "href" values in the presence of XML entities
- curl: unescape "href" values
* input
- nfs: fix crash bug
- nfs: fix freeze bug on reconnect
* decoder
- gme: adapt to API change in the upcoming version 0.7.0
* output
- alsa: implement channel mapping for 5.0 and 7.0
* player
- drain outputs at end of song in "single" mode
* Windows
- fix case insensitive search
ver 0.21.22 (2020/04/02)
* database
- simple: optimize startup
* input
- curl: fix streaming errors on Android
* playlist
- rss: support MIME type application/xml
* mixer
- android: new mixer plugin for "sles" output
* Android
- TV support
* Windows
- fix time zone offset check
* fix build failures with uClibc-ng
ver 0.21.21 (2020/03/19)
* configuration
- fix bug in "metadata_to_use" setting
* playlist
- asx, xspf: fix corrupt tags in the presence of XML entities
* archive
- iso9660: skip empty file names to work around libcdio bug
* decoder
- gme: ignore empty tags
* output
- solaris: port to NetBSD
* raise default "max_connections" value to 100
ver 0.21.20 (2020/02/16)
* decoder
- audiofile, ffmpeg, sndfile: handle MIME type "audio/wav"
- ffmpeg: fix playback of AIFF and TTA
- vorbis, opus: fix seeking in small files
* fix backwards seeking on ARM (and other non-x86 CPUs)
ver 0.21.19 (2020/01/17)
* configuration
- allow overriding top-level settings in includes
* output
- pulse: obey Pulse's maximum sample rate (fixes DSD128 playback)
* fix build failure with clang 10
* fix build failure with Android NDK r20
ver 0.21.18 (2019/12/24)
* protocol
- work around Mac OS X bug in the ISO 8601 parser
* output
- alsa: fix hang bug with ALSA "null" outputs
* storage
- curl: fix crash bug
* drop support for CURL versions older than 7.32.0
* reduce unnecessary CPU wakeups
ver 0.21.17 (2019/12/16)
* protocol
- relax the ISO 8601 parser: allow omitting field separators, the
time of day and the "Z" suffix
* archive
- zzip: improve error reporting
* outputs
- jack: mark ports as terminal
- shout: declare metadata as UTF-8
* fix build failure with -Ddatabase=false
ver 0.21.16 (2019/10/16)
* queue
- fix relative destination offset when moving a range
* storage
- curl: request the "resourcetype" property to fix database update
- curl: URL-encode more paths
- curl: follow redirects for collections without trailing slash
* update
- fix crash when music_directory is not a directory
* fix build with iconv() instead of ICU
ver 0.21.15 (2019/09/25)
* decoder
- dsdiff, dsf: fix displayed bit rate
- mpcdec: fix bogus ReplayGain values
* output
- solaris: fix build with glibc 2.30
ver 0.21.14 (2019/08/21)
* decoder
- sidplay: show track durations in database
- sidplay: convert tag values from Windows-1252 charset
- sidplay: strip text from "Date" tag
* player
- fix crash after song change
- fix seek position after restarting the decoder
* protocol
- include command name in error responses
ver 0.21.13 (2019/08/06)
* input
- cdio_paranoia: require libcdio-paranoia 10.2+0.93+1

View File

@@ -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

View File

@@ -2,18 +2,28 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.musicpd"
android:installLocation="auto"
android:versionCode="36"
android:versionName="0.21.13">
android:versionCode="62"
android:versionName="0.23.2">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="26"/>
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="29"/>
<uses-feature android:name="android.software.leanback"
android:required="false" />
<uses-feature android:name="android.hardware.touchscreen"
android:required="false" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<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">
<activity android:name=".Settings"
android:label="@string/app_name">
@@ -22,9 +32,18 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".Settings"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
</activity>
<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"/>

View File

@@ -24,26 +24,29 @@ android_abis = {
'armeabi-v7a': {
'arch': 'arm-linux-androideabi',
'ndk_arch': 'arm',
'toolchain_arch': 'arm-linux-androideabi',
'llvm_triple': 'armv7-none-linux-androideabi',
'cflags': '-march=armv7-a -mfpu=vfp -mfloat-abi=softfp',
'llvm_triple': 'armv7-linux-androideabi',
'cflags': '-fpic -mfpu=neon -mfloat-abi=softfp',
},
'arm64-v8a': {
'android_api_level': '21',
'arch': 'aarch64-linux-android',
'ndk_arch': 'arm64',
'toolchain_arch': 'aarch64-linux-android',
'llvm_triple': 'aarch64-none-linux-android',
'cflags': '',
'llvm_triple': 'aarch64-linux-android',
'cflags': '-fpic',
},
'x86': {
'arch': 'i686-linux-android',
'ndk_arch': 'x86',
'toolchain_arch': 'x86',
'llvm_triple': 'i686-none-linux-android',
'cflags': '-march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32',
'llvm_triple': 'i686-linux-android',
'cflags': '-fPIC -march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32',
},
'x86_64': {
'arch': 'x86_64-linux-android',
'ndk_arch': 'x86_64',
'llvm_triple': 'x86_64-linux-android',
'cflags': '-fPIC -m64',
},
}
@@ -76,53 +79,38 @@ class AndroidNdkToolchain:
ndk_arch = abi_info['ndk_arch']
android_api_level = '21'
ndk_platform = 'android-' + android_api_level
# select the NDK compiler
gcc_version = '4.9'
ndk_platform_path = os.path.join(ndk_path, 'platforms', ndk_platform)
sysroot = os.path.join(ndk_path, 'sysroot')
target_root = os.path.join(ndk_platform_path, 'arch-' + ndk_arch)
install_prefix = os.path.join(arch_path, 'root')
self.arch = arch
self.actual_arch = arch
self.install_prefix = install_prefix
self.sysroot = sysroot
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']
llvm_triple = abi_info['llvm_triple'] + android_api_level
common_flags = '-Os -g'
common_flags += ' -fPIC'
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'
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
self.cppflags = '--sysroot=' + sysroot + \
' -isystem ' + os.path.join(install_prefix, 'include') + \
' -isystem ' + os.path.join(sysroot, 'usr', 'include', arch) + \
' -D__ANDROID_API__=' + android_api_level
self.ldflags = '--sysroot=' + sysroot + \
' -L' + os.path.join(install_prefix, 'lib') + \
' -L' + os.path.join(target_root, 'usr', 'lib') + \
' -B' + os.path.join(target_root, 'usr', 'lib') + \
self.cppflags = ' -isystem ' + os.path.join(install_prefix, 'include')
self.ldflags = ' -L' + os.path.join(install_prefix, 'lib') + \
' -Wl,--exclude-libs=ALL' + \
' ' + common_flags
self.ldflags = common_flags
self.libs = ''
self.is_arm = ndk_arch == 'arm'
@@ -130,13 +118,10 @@ class AndroidNdkToolchain:
self.is_aarch64 = ndk_arch == 'arm64'
self.is_windows = False
libcxx_path = os.path.join(ndk_path, 'sources/cxx-stl/llvm-libc++')
libcxx_libs_path = os.path.join(libcxx_path, 'libs', android_abi)
libstdcxx_flags = ''
libstdcxx_cxxflags = libstdcxx_flags + ' -isystem ' + os.path.join(libcxx_path, 'include') + ' -isystem ' + os.path.join(ndk_path, 'sources/android/support/include')
libstdcxx_ldflags = libstdcxx_flags + ' -L' + libcxx_libs_path
libstdcxx_libs = '-lc++_static -lc++abi'
libstdcxx_cxxflags = ''
libstdcxx_ldflags = ''
libstdcxx_libs = '-static-libstdc++'
if self.is_armv7:
# On 32 bit ARM, clang generates no ".eh_frame" section;
@@ -155,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
@@ -168,13 +150,15 @@ from build.libs import *
thirdparty_libs = [
libmpdclient,
libogg,
libvorbis,
opus,
flac,
libid3tag,
libmodplug,
wildmidi,
gme,
ffmpeg,
openssl,
curl,
libexpat,
libnfs,
boost,
]

View File

@@ -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)

View File

@@ -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"

View File

@@ -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>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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();
}

View File

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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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,11 +21,16 @@ package org.musicpd;
import android.annotation.TargetApi;
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;
@@ -35,6 +40,9 @@ import android.os.RemoteException;
import android.util.Log;
import android.widget.RemoteViews;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class Main extends Service implements Runnable {
private static final String TAG = "Main";
private static final String REMOTE_ERROR = "MPD process was killed";
@@ -51,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 {
@@ -64,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);
}
@@ -156,11 +168,58 @@ public class Main extends Service implements Runnable {
sendMessage(MSG_SEND_STATUS, mStatus, 0, mError);
}
private Notification.Builder createNotificationBuilderWithChannel() {
final NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
if (notificationManager == null)
return null;
final String id = "org.musicpd";
final String name = "MPD service";
final int importance = 3; /* NotificationManager.IMPORTANCE_DEFAULT */
try {
Class<?> ncClass = Class.forName("android.app.NotificationChannel");
Constructor<?> ncCtor = ncClass.getConstructor(String.class, CharSequence.class, int.class);
Object nc = ncCtor.newInstance(id, name, importance);
Method nmCreateNotificationChannelMethod =
NotificationManager.class.getMethod("createNotificationChannel", ncClass);
nmCreateNotificationChannelMethod.invoke(notificationManager, nc);
Constructor nbCtor = Notification.Builder.class.getConstructor(Context.class, String.class);
return (Notification.Builder) nbCtor.newInstance(this, id);
} catch (Exception e)
{
Log.e(TAG, "error creating the NotificationChannel", e);
return null;
}
}
private void start() {
if (mThread != null)
return;
mThread = new Thread(this);
mThread.start();
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");
@@ -168,13 +227,25 @@ public class Main extends Service implements Runnable {
final PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
mainIntent, PendingIntent.FLAG_CANCEL_CURRENT);
Notification notification = new Notification.Builder(this)
.setContentTitle(getText(R.string.notification_title_mpd_running))
Notification.Builder nBuilder;
if (Build.VERSION.SDK_INT >= 26 /* Build.VERSION_CODES.O */)
{
nBuilder = createNotificationBuilderWithChannel();
if (nBuilder == null)
return;
}
else
nBuilder = new Notification.Builder(this);
Notification notification = nBuilder.setContentTitle(getText(R.string.notification_title_mpd_running))
.setContentText(getText(R.string.notification_text_mpd_running))
.setSmallIcon(R.drawable.notification_icon)
.setContentIntent(contentIntent)
.build();
mThread = new Thread(this);
mThread.start();
startForeground(R.string.notification_title_mpd_running, notification);
startService(new Intent(this, Main.class));
}
@@ -200,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);
@@ -327,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) {
@@ -373,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);
}
}

View File

@@ -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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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);
@@ -105,12 +106,13 @@ public class Settings extends Activity {
else
mRunButton.setChecked(false);
mFirstRun = true;
mTextStatus.setText("");
break;
case MSG_STARTED:
Log.d(TAG, "onStarted");
mRunButton.setChecked(true);
mFirstRun = true;
mTextStatus.setText("CAUTION: this version is EXPERIMENTAL!"); // XXX
mTextStatus.setText("MPD service started");
break;
case MSG_LOG:
if (mLogListArray.size() > MAX_LOGS)
@@ -153,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();
}
@@ -178,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
@@ -210,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
View 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.

View File

@@ -30,7 +30,7 @@ master_doc = 'index'
# General information about the project.
project = 'Music Player Daemon'
copyright = '2003-2018 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.21.13'
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.
@@ -212,3 +212,7 @@ html_static_path = ['_static']
# implements a search results scorer. If empty, the default will be used.
#
# html_search_scorer = 'scorer.js'
man_pages = [
('mpd.1', 'mpd', 'MPD documentation', [author], 1),
('mpd.conf.5', 'mpd.conf', 'mpd.conf documentation', [author], 5)
]

View File

@@ -12,8 +12,7 @@ Code Style
* indent with tabs (width 8)
* don't write CPP when you can write C++: use inline functions and constexpr instead of macros
* comment your code, document your APIs
* the code should be C++14 compliant, and must compile with :program:`GCC` 6.0 and :program:`clang` 3.4
* report error conditions with C++ exceptions, preferable derived from :envvar:`std::runtime_error`
* the code should be C++17 compliant, and must compile with :program:`GCC` 8 and :program:`clang` 5
* all code must be exception-safe
* classes and functions names use CamelCase; variables are lower-case with words separated by underscore
@@ -31,6 +30,56 @@ Some example code:
return xyz;
}
Error handling
==============
If an error occurs, throw a C++ exception, preferably derived from
:code:`std::runtime_error`. The function's API documentation should
mention that. If a function cannot throw exceptions, add
:code:`noexcept` to its prototype.
Some parts of MPD use callbacks to report completion; the handler
classes usually have an "error" callback which receives a
:code:`std::exception_ptr`
(e.g. :code:`BufferedSocket::OnSocketError()`). Wrapping errors in
:code:`std::exception_ptr` allows propagating details about the error
across thread boundaries to the entity which is interested in handling
it (e.g. giving the MPD client details about an I/O error caught by
the decoder thread).
Out-of-memory errors (i.e. :code:`std::bad_alloc`) do not need to be
handled. Some operating systems such as Linux do not report
out-of-memory to userspace, and instead kill a process to recover.
Even if we know we are out of memory, there is little we can do except
for aborting the process quickly. Any other attempts to give back
memory may cause page faults on the way which make the situation
worse.
Error conditions which are caused by a bug do not need to be handled
at runtime; instead, use :code:`assert()` to detect them in debug
builds.
git Branches
************
There are two active branches in the git repository:
- the "unstable" branch called ``master`` where new features are
merged. This will become the next major release eventually.
- the "stable" branch (currently called ``v0.22.x``) where only bug
fixes are merged.
Once :program:`MPD` 0.23 is released, a new branch called ``v0.23.x``
will be created for 0.23 bug-fix releases; after that, ``v0.22.x``
will eventually cease to be maintained.
After bug fixes have been added to the "stable" branch, it will be
merged into ``master``. This ensures that all known bugs are fixed in
all active branches.
Hacking The Source
******************

View File

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

View File

@@ -1,33 +1,38 @@
install_man(['mpd.1', 'mpd.conf.5'])
if not get_option('html_manual') and not get_option('manpages')
subdir_done()
endif
sphinx = find_program('sphinx-build')
sphinx_output = custom_target(
'HTML documentation',
output: 'html',
input: [
'index.rst', 'user.rst', 'developer.rst',
'plugins.rst',
'protocol.rst',
'conf.py',
],
command: [sphinx, '-q', '-b', 'html', '-d', '@OUTDIR@/doctrees', meson.current_source_dir(), '@OUTPUT@'],
build_by_default: true,
install: true,
install_dir: join_paths(get_option('datadir'), 'doc', meson.project_name()),
)
sphinx = find_program('sphinx-build', required: get_option('documentation'))
if not sphinx.found()
subdir_done()
endif
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=*',
],
)
if get_option('html_manual')
sphinx_output = custom_target(
'HTML documentation',
output: 'html',
input: [
'index.rst', 'user.rst', 'developer.rst',
'plugins.rst',
'client.rst',
'protocol.rst',
'conf.py',
],
command: [sphinx, '-q', '-b', 'html', '-d', '@OUTDIR@/doctrees', meson.current_source_dir(), '@OUTPUT@'],
build_by_default: true,
install: true,
install_dir: join_paths(get_option('datadir'), 'doc', meson.project_name()),
)
endif
if get_option('manpages')
custom_target(
'Manpage documentation',
output: ['mpd.1', 'mpd.conf.5'],
input: ['mpd.1.rst', 'conf.py'],
command: [sphinx, '-q', '-b', 'man', '-d', '@OUTDIR@/man_doctrees', meson.current_source_dir(), '@OUTDIR@'],
build_by_default: true,
install: true,
install_dir: [join_paths(get_option('mandir'), 'man1'), join_paths(get_option('mandir'), 'man5')],
)
endif

View File

@@ -1,55 +0,0 @@
.TH "Music Player Daemon" 1
.SH NAME
MPD \- A daemon for playing music
.SH SYNOPSIS
.B mpd
.RI [ options ]
.RI [ CONF_FILE ]
.SH 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 \fB$XDG_CONFIG_HOME/mpd/mpd.conf\fP then
\fB~/.mpdconf\fP then \fB/etc/mpd.conf\fP or uses CONF_FILE.
Read more about MPD at <\fBhttp://www.musicpd.org/\fP>.
.SH OPTIONS
.TP
.BI \-\-help
Output a brief help message.
.TP
.BI \-\-kill
Kill the currently running mpd session. The pid_file parameter must be
specified in the config file for this to work.
.TP
.BI \-\-no\-daemon
Don't detach from console.
.TP
.BI \-\-stderr
Print messages stderr.
.TP
.BI \-\-verbose
Verbose logging.
.TP
.BI \-\-version
Print version information.
.SH FILES
.TP
.BI ~/.mpdconf
User configuration file.
.TP
.BI /etc/mpd.conf
Global configuration file.
.SH SEE ALSO
mpd.conf(5), mpc(1)
.SH BUGS
If you find a bug, please report it at
.br
<\fBhttps://github.com/MusicPlayerDaemon/MPD/issues/\fP>.
.SH AUTHORS
Max Kellermann <max.kellermann@gmail.com>
Special thanks to all the people that provided feedback and patches.

69
doc/mpd.1.rst Normal file
View File

@@ -0,0 +1,69 @@
===
mpd
===
SYNOPSIS
--------
``mpd`` [options] [CONF_FILE]
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 ``~/.mpd/mpd.conf`` then ``/etc/mpd.conf`` or uses ``CONF_FILE``.
Read more about MPD at http://www.musicpd.org/
OPTIONS
-------
.. program:: mpd
.. option:: --help
Output a brief help message.
.. option:: --kill
Kill the currently running mpd session. The pid_file parameter must be specified in the config file for this to work.
.. option:: --no-config
Don't read from the configuration file.
.. option:: --no-daemon
Don't detach from console.
.. option:: --stderr
Print messages to stderr.
.. option:: --verbose
Verbose logging.
.. option:: --version
Print version information.
FILES
-----
:file:`$XDG_CONFIG_HOME/mpd/mpd.conf`
User configuration file (usually :file:`~/.config/mpd/mpd.conf`).
:file:`/etc/mpd.conf`
Global configuration file.
SEE ALSO
--------
:manpage:`mpd.conf(5)`, :manpage:`mpc(1)`
BUGS
----
If you find a bug, please report it at https://github.com/MusicPlayerDaemon/MPD/issues/

View File

@@ -1,180 +0,0 @@
.TH mpd.conf 5
.SH NAME
mpd.conf \- Music Player Daemon configuration file
.SH DESCRIPTION
\fBmpd.conf\fP is the configuration file for mpd(1). If not specified on the
command line, MPD first searches for it at \fB$XDG_CONFIG_HOME/mpd/mpd.conf\fP
then at \fB~/.mpdconf\fP then at \fB~/.mpd/mpd.conf\fP and then in
\fB/etc/mpd.conf\fP.
Lines beginning with a "#" 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:
parameter "value"
The exception to this rule is the audio_output parameter, which is of the form:
audio_output {
.br
parameter1 "value"
parameter2 "value"
.br
}
Parameters that take a file or directory as an argument should use absolute
paths.
See \fBdocs/mpdconf.example\fP in the source tarball for an example
configuration file.
This manual is not complete, it lists only the most important options.
Please read the MPD user manual for a complete configuration guide:
<\fBhttp://www.musicpd.org/doc/user/\fP>
.SH REQUIRED PARAMETERS
.TP
.B db_file <file>
This specifies where the db file will be stored.
.TP
.B log_file <file>
This specifies where the log file should be located.
The special value "syslog" makes MPD use the local syslog daemon.
.SH OPTIONAL PARAMETERS
.TP
.B sticker_file <file>
The location of the sticker database. This is a database which
manages dynamic information attached to songs.
.TP
.B pid_file <file>
This specifies the file to save mpd's process ID in.
.TP
.B music_directory <directory>
This specifies the directory where music is located.
If you do not configure this, you can only play streams.
.TP
.B playlist_directory <directory>
This specifies the directory where saved playlists are stored.
If you do not configure this, you cannot save playlists.
.TP
.B state_file <file>
This specifies if a state file is used and where it is located. The state of
mpd will be saved to this file when mpd is terminated by a TERM signal or by
the "kill" command. When mpd is restarted, it will read the state file and
restore the state of mpd (including the playlist).
.TP
.B restore_paused <yes or no>
Put MPD into pause mode instead of starting playback after startup.
.TP
.B user <username>
This specifies the user that MPD will run as, if set. MPD should
never run as root, and you may use this option to make MPD change its
user id after initialization. Do not use this option if you start MPD
as an unprivileged user.
.TP
.B port <port>
This specifies the port that mpd listens on. The default is 6600.
.TP
.B log_level <default, secure, or verbose>
This specifies how verbose logs are. "default" is minimal logging, "secure"
reports from what address a connection is opened, and when it is closed, and
"verbose" records excessive amounts of information for debugging purposes. The
default is "default".
.TP
.B follow_outside_symlinks <yes or no>
Control if MPD will follow symbolic links pointing outside the music dir.
You must recreate the database after changing this option.
The default is "yes".
.TP
.B follow_inside_symlinks <yes or no>
Control if MPD will follow symbolic links pointing inside the music dir,
potentially adding duplicates to the database.
You must recreate the database after changing this option.
The default is "yes".
.TP
.B zeroconf_enabled <yes or no>
If yes, and MPD has been compiled with support for Avahi or Bonjour, service
information will be published with Zeroconf. The default is yes.
.TP
.B zeroconf_name <name>
If Zeroconf is enabled, this is the service name to publish. This name should
be unique to your local network, but name collisions will be properly dealt
with. The default is "Music Player @ %h", where %h will be replaced with the
hostname of the machine running MPD.
.TP
.B audio_output
See \fBDESCRIPTION\fP and the various \fBAUDIO OUTPUT PARAMETERS\fP sections
for the format of this parameter. Multiple audio_output sections may be
specified. If no audio_output section is specified, then MPD will scan for a
usable audio output.
.TP
.B replaygain <off or album or track or auto>
If specified, mpd will adjust the volume of songs played using ReplayGain tags
(see <\fBhttp://www.replaygain.org/\fP>). Setting this to "album" will adjust
volume using the album's ReplayGain tags, while setting it to "track" will
adjust it using the track ReplayGain tags. "auto" uses the track ReplayGain
tags if random play is activated otherwise the album ReplayGain tags. Currently
only FLAC, Ogg Vorbis, Musepack, and MP3 (through ID3v2 ReplayGain tags, not
APEv2) are supported.
.TP
.B replaygain_preamp <\-15 to 15>
This is the gain (in dB) applied to songs with ReplayGain tags.
.TP
.B volume_normalization <yes or no>
If yes, mpd will normalize the volume of songs as they play. The default is no.
.TP
.B filesystem_charset <charset>
This specifies the character set used for the filesystem. A list of supported
character sets can be obtained by running "iconv \-l". The default is
determined from the locale when the db was originally created.
.TP
.B save_absolute_paths_in_playlists <yes or no>
This specifies whether relative or absolute paths for song filenames are used
when saving playlists. The default is "no".
.TP
.B auto_update <yes or no>
This specifies the whether to support automatic update of music database when
files are changed in music_directory. The default is to disable autoupdate
of database.
.TP
.B auto_update_depth <N>
Limit the depth of the directories being watched, 0 means only watch
the music directory itself. There is no limit by default.
.SH REQUIRED AUDIO OUTPUT PARAMETERS
.TP
.B type <type>
This specifies the audio output type. See the list of supported outputs in mpd
\-\-version for possible values.
.TP
.B name <name>
This specifies a unique name for the audio output.
.SH OPTIONAL AUDIO OUTPUT PARAMETERS
.TP
.B format <sample_rate:bits:channels>
This specifies the sample rate, bits per sample, and number of channels of
audio that is sent to the audio output device. See documentation for the
\fBaudio_output_format\fP parameter for more details. The default is to use
whatever audio format is passed to the audio output.
Any of the three attributes may be an asterisk to specify that this
attribute should not be enforced
.TP
.B replay_gain_handler <software, mixer or none>
Specifies how replay gain is applied. The default is "software",
which uses an internal software volume control. "mixer" uses the
configured (hardware) mixer control. "none" disables replay gain on
this audio output.
.TP
.B mixer_type <hardware, software or none>
Specifies which mixer should be used for this audio output: the
hardware mixer (available for ALSA, OSS and PulseAudio), the software
mixer or no mixer ("none"). By default, the hardware mixer is used
for devices which support it, and none for the others.
.SH FILES
.TP
.BI ~/.mpdconf
User configuration file.
.TP
.BI /etc/mpd.conf
Global configuration file.
.SH SEE ALSO
mpd(1), mpc(1)

210
doc/mpd.conf.5.rst Normal file
View File

@@ -0,0 +1,210 @@
========
mpd.conf
========
DESCRIPTION
------------
:file:`mpd.conf` is the configuration file for :manpage:`mpd(1)`. If
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`.
Each line in the configuration file contains a setting name and its value, e.g.:
:code:`connection_timeout "5"`
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 {
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:
: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.
This manual is not complete, it lists only the most important options.
Please read the MPD user manual for a complete configuration guide:
http://www.musicpd.org/doc/user/
OPTIONAL PARAMETERS
-------------------
db_file <file>
This specifies where the db file will be stored.
log_file <file>
This specifies where the log file should be located. The special value "syslog" makes MPD use the local syslog daemon.
sticker_file <file>
The location of the sticker database. This is a database which manages
dynamic information attached to songs.
pid_file <file>
This specifies the file to save mpd's process ID in.
music_directory <directory>
This specifies the directory where music is located. If you do not configure
this, you can only play streams.
playlist_directory <directory>
This specifies the directory where saved playlists are stored. If
you do not configure this, you cannot save playlists.
state_file <file>
This specifies if a state file is used and where it is located. The state of
mpd will be saved to this file when mpd is terminated by a TERM signal or by
the :program:`kill` command. When mpd is restarted, it will read the state file and
restore the state of mpd (including the playlist).
restore_paused <yes or no>
Put MPD into pause mode instead of starting playback after startup.
user <username>
This specifies the user that MPD will run as, if set. MPD should never run
as root, and you may use this option to make MPD change its user id after
initialization. Do not use this option if you start MPD as an unprivileged
user.
port <port>
This specifies the port that mpd listens on. The default is 6600.
log_level <level>
Suppress all messages below the given threshold. The following
log levels are available:
- :samp:`error`: errors
- :samp:`warning`: warnings
- :samp:`notice`: interesting informational messages
- :samp:`info`: unimportant informational messages
- :samp:`verbose`: debug messages (for developers and for
troubleshooting)
The default is :samp:`notice`.
follow_outside_symlinks <yes or no>
Control if MPD will follow symbolic links pointing outside the music dir. You
must recreate the database after changing this option. The default is "yes".
follow_inside_symlinks <yes or no>
Control if MPD will follow symbolic links pointing inside the music dir,
potentially adding duplicates to the database. You must recreate the
database after changing this option. The default is "yes".
zeroconf_enabled <yes or no>
If yes, and MPD has been compiled with support for Avahi or Bonjour, service
information will be published with Zeroconf. The default is yes.
zeroconf_name <name>
If Zeroconf is enabled, this is the service name to publish. This name should
be unique to your local network, but name collisions will be properly dealt
with. The default is "Music Player @ %h", where %h will be replaced with the
hostname of the machine running MPD.
audio_output
See DESCRIPTION and the various ``AUDIO OUTPUT PARAMETERS`` sections for the
format of this parameter. Multiple audio_output sections may be specified. If
no audio_output section is specified, then MPD will scan for a usable audio
output.
replaygain <off or album or track or auto>
If specified, mpd will adjust the volume of songs played using ReplayGain
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
tags. Currently only FLAC, Ogg Vorbis, Musepack, and MP3 (through ID3v2
ReplayGain tags, not APEv2) are supported.
replaygain_preamp <-15 to 15>
This is the gain (in dB) applied to songs with ReplayGain tags.
volume_normalization <yes or no>
If yes, mpd will normalize the volume of songs as they play. The default is
no.
filesystem_charset <charset>
This specifies the character set used for the filesystem. A list of supported
character sets can be obtained by running "iconv -l". The default is
determined from the locale when the db was originally created.
save_absolute_paths_in_playlists <yes or no>
This specifies whether relative or absolute paths for song filenames are used
when saving playlists. The default is "no".
auto_update <yes or no>
This specifies the whether to support automatic update of music database
when files are changed in music_directory. The default is to disable
autoupdate of database.
auto_update_depth <N>
Limit the depth of the directories being watched, 0 means only watch the
music directory itself. There is no limit by default.
REQUIRED AUDIO OUTPUT PARAMETERS
--------------------------------
type <type>
This specifies the audio output type. See the list of supported outputs in
``mpd --version`` for possible values.
name <name>
This specifies a unique name for the audio output.
OPTIONAL AUDIO OUTPUT PARAMETERS
--------------------------------
format <sample_rate:bits:channels>
This specifies the sample rate, bits per sample, and number of channels of
audio that is sent to the audio output device. See documentation for the
``audio_output_format`` parameter for more details. The default is to use
whatever audio format is passed to the audio output. Any of the three
attributes may be an asterisk to specify that this attribute should not be
enforced
replay_gain_handler <software, mixer or none>
Specifies how replay gain is applied. The default is "software", which uses
an internal software volume control. "mixer" uses the configured (hardware)
mixer control. "none" disables replay gain on this audio output.
mixer_type <hardware, software or none>
Specifies which mixer should be used for this audio output: the hardware
mixer (available for ALSA, OSS and PulseAudio), the software mixer or no
mixer ("none"). By default, the hardware mixer is used for devices which
support it, and none for the others.
FILES
-----
:file:`$XDG_CONFIG_HOME/mpd/mpd.conf`
User configuration file (usually :file:`~/.config/mpd/mpd.conf`).
:file:`/etc/mpd.conf`
Global configuration file.
SEE ALSO
--------
:manpage:`mpd(1)`, :manpage:`mpc(1)`

View 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.
#
@@ -89,12 +89,11 @@
#
#port "6600"
#
# This setting controls the type of information which is logged. Available
# setting arguments are "default", "secure" or "verbose". The "verbose" setting
# argument is recommended for troubleshooting, though can quickly stretch
# available resources on limited hardware storage.
# Suppress all messages below the given threshold. Use "verbose" for
# troubleshooting. Available setting arguments are "notice", "info", "verbose",
# "warning" and "error".
#
#log_level "default"
#log_level "notice"
#
# Setting "restore_paused" to "yes" puts MPD into pause mode instead
# of starting playback after startup.
@@ -115,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"
@@ -130,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"
@@ -165,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"
#
@@ -174,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"
@@ -183,7 +193,6 @@
# Input #######################################################################
#
input {
plugin "curl"
# proxy "proxy.isp.com:8080"
@@ -196,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.
#
@@ -280,6 +289,7 @@ input {
# name "My Pulse Output"
## server "remote_server" # optional
## sink "remote_server_sink" # optional
## media_role "media_role" #optional
#}
#
# An example of a winmm output (Windows multimedia API).
@@ -293,6 +303,20 @@ input {
## mixer_type "hardware" # optional
#}
#
# An example of a wasapi output (Windows multimedia API).
#
#audio_output {
# type "wasapi"
# name "My WASAPI output"
## device "Digital Audio (S/PDIF) (High Definition Audio Device)" # optional
# or
## device "0" # optional
## Exclusive mode blocks all other audio source, and get best audio quality without resampling.
## exclusive "no" # optional
## Enumerate all devices in log.
## enumerate "no" # optional
#}
#
# An example of an openal output.
#
#audio_output {
@@ -348,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"
@@ -373,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"
@@ -382,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"

View File

@@ -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 run 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
@@ -42,7 +54,7 @@ Provides access to the database of another :program:`MPD` instance using libmpdc
* - **password**
- The password used to log in to the "master" :program:`MPD` instance.
* - **keepalive yes|no**
- Send TCP keepalive packets to the "master" :program:`MPD` instance? This option can help avoid certain firewalls dropping inactive connections, at the expensive of a very small amount of additional network traffic. Disabled by default.
- Send TCP keepalive packets to the "master" :program:`MPD` instance? This option can help avoid certain firewalls dropping inactive connections, at the expense of a very small amount of additional network traffic. Disabled by default.
upnp
----
@@ -60,25 +72,30 @@ The default plugin which gives :program:`MPD` access to local files. It is used
curl
----
A WebDAV client using libcurl. It is used when :code:`music_directory` contains a http:// or https:// URI, for example :samp:`https://the.server/dav/`.
A WebDAV client using libcurl. It is used when :code:`music_directory`
contains a ``http://`` or ``https://`` URI, for example
:samp:`https://the.server/dav/`.
smbclient
---------
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`.
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
---
Load music files from a NFS server. It is used when :code:`music_directory` contains a nfs:// URI according to RFC2224, for example :samp:`nfs://servername/path`.
Load music files from a NFS server. It is used when
:code:`music_directory` contains a ``nfs://`` URI according to
RFC2224, for example :samp:`nfs://servername/path`.
This plugin uses libnfs, which supports only NFS version 3. Since :program:`MPD` is not allowed to bind to "privileged ports", the NFS server needs to enable the "insecure" setting; example :file:`/etc/exports`:
.. code-block:: none
/srv/mp3 192.168.1.55(ro,insecure)
Don't fear: "insecure" does not mean that your NFS server is insecure. A few decades ago, people thought the concept of "privileged ports" would make network services "secure", which was a fallacy. The absence of this obsolete "security" measure means little.
See :ref:`input_nfs` for more information.
udisks
------
@@ -116,7 +133,7 @@ Provides a list of SMB/CIFS servers on the local network.
udisks
------
Queries the udisks2 daemon via D-Bus and obtain a list of file systems (e.g. USB sticks or other removable media).
Queries the udisks2 daemon via D-Bus and obtains a list of file systems (e.g. USB sticks or other removable media).
upnp
----
@@ -131,15 +148,39 @@ Input plugins
alsa
----
Allows :program:`MPD` on Linux to play audio directly from a soundcard using the scheme alsa://. Audio is formatted as 44.1 kHz 16-bit stereo (CD format). Examples:
Allows :program:`MPD` on Linux to play audio directly from a soundcard using the scheme alsa://. Audio is by default formatted as 48 kHz 16-bit stereo, but this default can be overidden by a config file setting or by the URI. Examples:
.. code-block:: none
mpc add alsa:// plays audio from device hw:0,0
mpc add alsa:// plays audio from device default
.. code-block:: none
mpc add alsa://hw:1,0 plays audio from device hw:1,0 cdio_paranoia
mpc add alsa://hw:1,0 plays audio from device hw:1,0
.. code-block:: none
mpc add alsa://hw:1,0?format=44100:16:2 plays audio from device hw:1,0 sampling 16-bit stereo at 44.1kHz.
.. list-table::
:widths: 20 80
:header-rows: 1
* - Setting
- Description
* - **default_device NAME**
- The alsa device id to use when none is specified in the URI.
* - **default_format F**
- The sampling rate, size and channels to use. Wildcards are not allowed.
Example - "44100:16:2"
* - **auto_resample yes|no**
- If set to no, then libasound will not attempt to resample. In this case, the user is responsible for ensuring that the requested sample rate can be produced natively by the device, otherwise an error will occur.
* - **auto_channels yes|no**
- If set to no, then libasound will not attempt to convert between different channel numbers. The user must ensure that the device supports the requested channels when sampling.
* - **auto_format yes|no**
- If set to no, then libasound will not attempt to convert between different sample formats (16 bit, 24 bit, floating point, ...). Again the user must ensure that the requested format is available natively from the device.
cdio_paranoia
-------------
@@ -162,7 +203,10 @@ curl
Opens remote files or streams over HTTP using libcurl.
Note that unless overridden by the below settings (e.g. by setting them to a blank value), general curl configuration from environment variables such as http_proxy or specified in :file:`~/.curlrc` will be in effect.
Note that unless overridden by the below settings (e.g. by setting
them to a blank value), general curl configuration from environment
variables such as ``http_proxy`` or specified in :file:`~/.curlrc`
will be in effect.
.. list-table::
:widths: 20 80
@@ -178,11 +222,15 @@ Note that unless overridden by the below settings (e.g. by setting them to a bla
- 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
------
Access to various network protocols implemented by the FFmpeg library: gopher://, rtp://, rtsp://, rtmp://, rtmpt://, rtmps://
Access to various network protocols implemented by the FFmpeg library:
``gopher://``, ``rtp://``, ``rtsp://``, ``rtmp://``, ``rtmpt://``,
``rtmps://``
file
----
@@ -194,30 +242,51 @@ mms
Plays streams with the MMS protocol using `libmms <https://launchpad.net/libmms>`_.
.. _input_nfs:
nfs
---
Allows :program:`MPD` to access files on NFSv3 servers without actually mounting them (i.e. in userspace, without help from the kernel's VFS layer). All URIs with the nfs:// scheme are used according to RFC2224. Example:
Allows :program:`MPD` to access files on NFS servers without actually
mounting them (i.e. with :program:`libnfs` in userspace, without help
from the kernel's VFS layer). All URIs with the ``nfs://`` scheme are
used according to RFC2224. Example:
.. code-block:: none
mpc add nfs://servername/path/filename.ogg
Note that this usually requires enabling the "insecure" flag in the server's /etc/exports file, because :program:`MPD` cannot bind to so-called "privileged" ports. Don't fear: this will not make your file server insecure; the flag was named in a time long ago when privileged ports were thought to be meaningful for security. By today's standards, NFSv3 is not secure at all, and if you believe it is, you're already doomed.
This plugin uses :program:`libnfs`, which supports only NFS version 3.
Since :program:`MPD` is not allowed to bind to so-called "privileged
ports", the NFS server needs to enable the ``insecure`` setting;
example :file:`/etc/exports`:
.. code-block:: none
/srv/mp3 192.168.1.55(ro,insecure)
Don't fear: this will not make your file server insecure; the flag was
named a time long ago when privileged ports were thought to be
meaningful for security. By today's standards, NFSv3 is not secure at
all, and if you believe it is, you're already doomed.
smbclient
---------
Allows :program:`MPD` to access files on SMB/CIFS servers (e.g. Samba or Microsoft Windows). All URIs with the smb:// scheme are used. Example:
Allows :program:`MPD` to access files on SMB/CIFS servers (e.g. Samba
or Microsoft Windows). All URIs with the ``smb://`` scheme are
used. Example:
.. code-block:: none
mpc add smb://servername/sharename/filename.ogg
mpc add smb://username:password@servername/sharename/filename.ogg
qobuz
-----
Play songs from the commercial streaming service Qobuz. It plays URLs in the form qobuz://track/ID, e.g.:
Play songs from the commercial streaming service Qobuz. It plays URLs
in the form ``qobuz://track/ID``, e.g.:
.. code-block:: none
@@ -240,35 +309,6 @@ Play songs from the commercial streaming service Qobuz. It plays URLs in the for
* - **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
@@ -298,6 +338,8 @@ faad
Decodes AAC files using libfaad.
.. _decoder_ffmpeg:
ffmpeg
------
@@ -319,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
@@ -333,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
----------
@@ -367,30 +417,22 @@ Video game music file emulator based on `game-music-emu <https://bitbucket.org/m
- Description
* - **accuracy yes|no**
- Enable more accurate sound emulation.
* - **default_fade**
- The default fade-out time, in seconds. Used by songs that don't specify their own fade-out time.
hybrid_dsd
----------
`Hybrid-DSD
<http://dsdmaster.blogspot.de/p/bitperfect-introduces-hybrid-dsd-file.html>`_
is a MP4 container file (:file:`*.m4a`) which contains both ALAC and
is an MP4 container file (:file:`*.m4a`) which contains both ALAC and
DSD data. It is disabled by default, and works only if you explicitly
enable it. Without this plugin, the ALAC parts gets handled by the
`FFmpeg decoder plugin
<https://www.musicpd.org/doc/user/decoder_plugins.html#ffmpeg_decoder>`_. This
:ref:`FFmpeg decoder plugin <decoder_ffmpeg>`. This
plugin should be enabled only if you have a bit-perfect playback path
to a DSD-capable DAC; for everybody else, playing back the ALAC copy
of the file is better.
.. list-table::
:widths: 20 80
:header-rows: 1
* - Setting
- Description
* - **gapless yes|no**
- This specifies whether to support gapless playback of MP3s which have the necessary headers. Useful if your MP3s have headers with incorrect information. If you have such MP3s, it is highly recommended that you fix them using `vbrfix <http://www.willwap.co.uk/Programs/vbrfix.php>`_ instead of disabling gapless MP3 playback. The default is to support gapless MP3 playback.
mad
---
@@ -423,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
------
@@ -434,7 +506,9 @@ Decodes Musepack files using `libmpcdec <http://www.musepack.net/>`_.
mpg123
------
Decodes MP3 files using `libmpg123 <http://www.mpg123.de/>`_.
Decodes MP3 files using `libmpg123 <http://www.mpg123.de/>`_. Currently, this
decoder does not support streams (e.g. archived files, remote files over HTTP,
...), only regular local files.
opus
----
@@ -444,7 +518,7 @@ Decodes Opus files using `libopus <http://www.opus-codec.org/>`_.
pcm
---
Read raw PCM samples. It understands the "audio/L16" MIME type with parameters "rate" and "channels" according to RFC 2586. It also understands the MPD-specific MIME type "audio/x-mpd-float".
Reads raw PCM samples. It understands the "audio/L16" MIME type with parameters "rate" and "channels" according to RFC 2586. It also understands the MPD-specific MIME type "audio/x-mpd-float".
sidplay
-------
@@ -458,9 +532,11 @@ C64 SID decoder based on `libsidplayfp <https://sourceforge.net/projects/sidplay
* - Setting
- Description
* - **songlength_database PATH**
- Location of your songlengths file, as distributed with the HVSC. The sidplay plugin checks this for matching MD5 fingerprints. See http://www.hvsc.c64.org/download/C64Music/DOCUMENTS/Songlengths.faq.
- Location of your songlengths file, as distributed with the HVSC. The sidplay plugin checks this for matching MD5 fingerprints. See http://www.hvsc.c64.org/download/C64Music/DOCUMENTS/Songlengths.faq. New songlength format support requires libsidplayfp 2.0 or later.
* - **default_songlength SECONDS**
- This is the default playing time in seconds for songs not in the songlength database, or in case you're not using a database. A value of 0 means play indefinitely.
* - **default_genre GENRE**
- Optional default genre for SID songs.
* - **filter yes|no**
- Turns the SID filter emulation on or off.
* - **kernal**
@@ -516,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
----
@@ -580,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.
@@ -652,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:
@@ -696,6 +780,29 @@ Valid quality values for libsoxr:
* "medium"
* "low"
* "quick"
* "custom"
If the quality is set to custom also the following settings are available:
.. list-table::
:widths: 20 80
:header-rows: 1
* - Name
- Description
* - **precision**
- The precision in bits. Valid values 16,20,24,28 and 32 bits.
* - **phase_response**
- Between the 0-100, Where 0=MINIMUM_PHASE and 50=LINEAR_PHASE.
* - **passband_end**
- The % of source bandwidth where to start filtering. Typical between the 90-99.7.
* - **stopband_begin**
- The % of the source bandwidth Where the anti aliasing filter start. Value 100+.
* - **attenuation**
- Reduction in dB's to prevent clipping from the resampling process.
* - **flags**
- Bitmask with additional option see soxr documentation for specific flags.
.. _output_plugins:
@@ -824,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
@@ -840,6 +951,10 @@ The jack plugin connects to a `JACK server <http://jackaudio.org/>`_.
- The names of the JACK source ports to be created. By default, the ports "left" and "right" are created. To use more ports, you have to tweak this option.
* - **destination_ports A,B**
- The names of the JACK destination ports to connect to.
* - **auto_destination_ports yes|no**
- If set to *yes*, then MPD will automatically create connections between the send ports of
MPD and receive ports of the first sound card; if set to *no*, then MPD will only create
connections to the contents of *destination_ports* if it is set. Enabled by default.
* - **ringbuffer_size NBYTES**
- Sets the size of the ring buffer for each channel. Do not configure this value unless you know what you're doing.
@@ -896,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:
@@ -958,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
@@ -974,6 +1113,8 @@ The pulse plugin connects to a `PulseAudio <http://www.freedesktop.org/wiki/Soft
- Sets the host name of the PulseAudio server. By default, :program:`MPD` connects to the local PulseAudio server.
* - **sink NAME**
- Specifies the name of the PulseAudio sink :program:`MPD` should play on.
* - **media_role ROLE**
- Specifies a custom media role that :program:`MPD` reports to PulseAudio. Default is "music". (optional).
* - **scale_volume FACTOR**
- Specifies a linear scaling coefficient (ranging from 0.5 to 5.0) to apply when adjusting volume through :program:`MPD`. For example, chosing a factor equal to ``"0.7"`` means that setting the volume to 100 in :program:`MPD` will set the PulseAudio volume to 70%, and a factor equal to ``"3.5"`` means that volume 100 in :program:`MPD` corresponds to a 350% PulseAudio volume.
@@ -1011,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**
@@ -1044,7 +1183,36 @@ sles
Plugin using the `OpenSL ES <https://www.khronos.org/opensles/>`__
audio API. Its primary use is local playback on Android, where
:ref:`ALSA <alsa_plugin>` is not available.
:ref:`ALSA <alsa_plugin>` is not available. It supports 16 bit and
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
@@ -1061,15 +1229,64 @@ The "Solaris" plugin runs only on SUN Solaris, and plays via /dev/audio.
- Sets the path of the audio device, defaults to /dev/audio.
wasapi
------
The `Windows Audio Session API <https://docs.microsoft.com/en-us/windows/win32/coreaudio/wasapi>`_ plugin uses WASAPI, which is supported started from Windows Vista. It is recommended if you are using Windows.
.. list-table::
:widths: 20 80
:header-rows: 1
* - Setting
- Description
* - **device NAME**
- Sets the device which should be used. This can be any valid audio device name, or index number. The default value is "", which makes WASAPI choose the default output device.
* - **enumerate yes|no**
- 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:
Filter plugins
==============
ffmpeg
------
Configures a FFmpeg filter graph.
This plugin requires building with ``libavfilter`` (FFmpeg).
.. list-table::
:widths: 20 80
:header-rows: 1
* - Setting
- Description
* - **graph "..."**
- Specifies the ``libavfilter`` graph; read the `FFmpeg
documentation
<https://ffmpeg.org/ffmpeg-filters.html#Filtergraph-syntax-1>`_
for details
hdcd
----
Decode `HDCD
<https://en.wikipedia.org/wiki/High_Definition_Compatible_Digital>`_.
This plugin requires building with ``libavfilter`` (FFmpeg).
normalize
---------
Normalize the volume during playback (at the expensve of quality).
Normalize the volume during playback (at the expense of quality).
null
@@ -1101,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
----
@@ -1125,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
----------
@@ -1148,3 +1367,19 @@ Download playlist from SoundCloud. It accepts URIs starting with soundcloud://.
xspf
----
Reads XSPF playlist files.
Archive plugins
===============
bz2
---
Allows to load single bzip2 compressed files using `libbz2 <https://www.sourceware.org/bzip2/>`_. Does not support seeking.
zzip
----
Allows to load music files from ZIP archives using `zziplib <http://zziplib.sourceforge.net/>`_.
iso
---
Allows to load music files from ISO 9660 images using `libcdio <https://www.gnu.org/software/libcdio/>`_.

View File

@@ -66,7 +66,19 @@ Binary Responses
Some commands can return binary data. This is initiated by a line
containing ``binary: 1234`` (followed as usual by a newline). After
that, the specified number of bytes of binary data follows, then a
newline, and finally the ``OK`` line. Example::
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. 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::
foo: bar
binary: 42
@@ -163,7 +175,7 @@ syntax::
find EXPRESSION
``EXPRESSION`` is a string enclosed in parantheses which can be one
``EXPRESSION`` is a string enclosed in parentheses which can be one
of:
- ``(TAG == 'VALUE')``: match a tag value; if there are multiple
@@ -209,15 +221,15 @@ of:
or more attributes may be ``*``).
- ``(!EXPRESSION)``: negate an expression. Note that each expression
must be enclosed in parantheses, e.g. :code:`(!(artist == 'VALUE'))`
must be enclosed in parentheses, e.g. :code:`(!(artist == 'VALUE'))`
(which is equivalent to :code:`(artist != 'VALUE')`)
- ``(EXPRESSION1 AND EXPRESSION2 ...)``: combine two or
more expressions with logical "and". Note that each expression must
be enclosed in parantheses, e.g. :code:`((artist == 'FOO') AND
be enclosed in parentheses, e.g. :code:`((artist == 'FOO') AND
(album == 'BAR'))`
The :command:`find` commands are case sensitive, which
The :command:`find` commands are case sensitive, while
:command:`search` and related commands ignore case.
Prior to MPD 0.21, the syntax looked like this::
@@ -272,8 +284,20 @@ 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>`_).
* **comment**: a human-readable comment about this song. The exact meaning of this tag is not well-defined.
* **disc**: the decimal disc number in a multi-disc album.
* **label**: the name of the label or publisher.
@@ -368,13 +392,19 @@ 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).
is identified in status). Information about the current song
is represented by key-value pairs, one on each line. The first
pair must be the `file` key-value pair.
.. _command_idle:
@@ -390,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
@@ -398,9 +430,11 @@ Querying :program:`MPD`'s status
- ``sticker``: the sticker database has been modified.
- ``subscription``: a client has subscribed or unsubscribed to a channel
- ``message``: a message was received on a channel this client is subscribed to; this event is only emitted when the queue is empty
- ``neighbor``: a neighbor was found or lost
- ``mount``: the mount list has changed
Change events accumulate, even while the connection is not in
"idle" mode; no events gets lost while the client is doing
"idle" mode; no events get lost while the client is doing
something else with the connection. If an event had already
occurred since the last call, the new :ref:`idle <command_idle>`
command will return immediately.
@@ -424,6 +458,8 @@ Querying :program:`MPD`'s status
Reports the current status of the player and the volume
level.
- ``partition``: the name of the current partition (see
:ref:`partition_commands`)
- ``volume``: ``0-100`` (deprecated: ``-1`` if the volume cannot
be determined)
- ``repeat``: ``0`` or ``1``
@@ -456,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.
@@ -464,23 +502,32 @@ Querying :program:`MPD`'s status
- ``songs``: number of songs
- ``uptime``: daemon uptime in seconds
- ``db_playtime``: sum of all song times in the database in seconds
- ``db_update``: last db update in UNIX time
- ``db_update``: last db update in UNIX time (seconds since
1970-01-01 UTC)
- ``playtime``: time length of music played
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.
@@ -490,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.
@@ -500,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``,
@@ -514,16 +579,20 @@ Playback options
``auto``
.
Changing the mode during playback may take several
seconds, because the new settings does not affect the
seconds, because the new settings do not affect the
buffered data.
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.
@@ -531,41 +600,59 @@ Playback options
Controlling playback
====================
.. _command_next:
:command:`next`
Plays next song in the playlist.
:command:`pause {PAUSE}`
Toggles pause/resumes playing, ``PAUSE`` is 0 or 1.
.. _command_pause:
The use of pause command without the PAUSE argument is deprecated.
: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.
@@ -600,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::
@@ -613,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.
@@ -621,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`
@@ -644,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
@@ -661,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
@@ -674,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
@@ -699,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
@@ -709,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
@@ -729,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
@@ -750,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
@@ -768,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.
@@ -807,12 +974,15 @@ remote playlists (absolute URI with a supported scheme).
The music database
==================
.. _command_albumart:
:command:`albumart {URI} {OFFSET}`
Searches the directory the file ``URI``
resides in and attempts to return a chunk of an album
Locate album art for the given song and return a chunk of an album
art image file at offset ``OFFSET``.
Uses the filename "cover" with any of ".png, .jpg,
.tiff, .bmp".
This is currently implemented by searching the directory the file
resides in for a file called :file:`cover.png`, :file:`cover.jpg`,
:file:`cover.tiff` or :file:`cover.bmp`.
Returns the file size and actual number
of bytes read at the requested offset, followed
@@ -821,10 +991,13 @@ The music database
Example::
albumart
albumart foo/bar.ogg 0
size: 1024768
binary: 8192
<8192 bytes>OK
<8192 bytes>
OK
.. _command_count:
:command:`count {FILTER} [group {GROUPTYPE}]`
Count the number of songs and their total playtime in
@@ -844,10 +1017,23 @@ The music database
count group artist
count title Echoes group artist
A group with an empty value contains counts of matching song which
don't this group tag. It exists only if at least one such song is
A group with an empty value contains counts of matching songs which
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)::
getfingerprint "foo/bar.ogg"
chromaprint: AQACcEmSREmWJJmkIT_6CCf64...
OK
This command is only available if MPD was built with
:file:`libchromaprint` (``-Dchromaprint=enabled``).
.. _command_find:
:command:`find {FILTER} [sort {TYPE}] [window {START:END}]`
@@ -874,11 +1060,11 @@ The music database
.. _command_findadd:
:command:`findadd {FILTER}`
: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:
@@ -927,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
@@ -963,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
@@ -979,9 +1169,35 @@ 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
reading embedded pictures from binary tags (e.g. ID3v2's ``APIC``
tag).
Returns the following values:
- ``size``: the total file size
- ``type``: the file's MIME type (optional)
- ``binary``: see :ref:`binary`
If the song file was recognized, but there is no picture, the
response is successful, but is otherwise empty.
Example::
readpicture foo/bar.ogg 0
size: 1024768
type: image/jpeg
binary: 8192
<8192 bytes>
OK
.. _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>`,
@@ -989,14 +1205,19 @@ The music database
.. _command_searchadd:
:command:`searchadd {FILTER}`
: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>`.
:command:`searchaddpl {NAME} {FILTER}`
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
the playlist named ``NAME``.
@@ -1021,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.
@@ -1036,8 +1259,8 @@ access NFS and SMB servers.
Multiple storages can be "mounted" together, similar to the
`mount` command on many operating
systems, but without cooperation from the kernel. No
superuser privileges are necessary, beause this mapping exists
only inside the :program:`MPD` process
superuser privileges are necessary, because this mapping exists
only inside the :program:`MPD` process.
.. _command_mount:
@@ -1047,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``.
@@ -1064,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
@@ -1099,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.
@@ -1130,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
@@ -1140,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`.
@@ -1147,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``
@@ -1167,25 +1429,35 @@ 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.
.. _partition_commands:
Partition commands
==================
@@ -1194,27 +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.
@@ -1223,7 +1518,7 @@ Audio output devices
:command:`outputs`
Shows information about all outputs.
::
outputid: 0
@@ -1239,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
@@ -1248,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"
@@ -1257,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::
@@ -1295,12 +1602,19 @@ additional services.
New messages are indicated by the ``message``
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.
@@ -1310,10 +1624,14 @@ idle event.
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.
@@ -1322,6 +1640,7 @@ idle event.
.. [#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

View File

@@ -44,7 +44,9 @@ ALSA is not available on Android; only the :ref:`OpenSL ES
Compiling from source
---------------------
Download the source tarball from the `MPD home page <https://musicpd.org>`_ and unpack it:
`Download the source tarball <https://www.musicpd.org/download.html>`_
and unpack it (or `clone the git repository
<https://github.com/MusicPlayerDaemon/MPD>`_):
.. code-block:: none
@@ -53,8 +55,8 @@ Download the source tarball from the `MPD home page <https://musicpd.org>`_ and
In any case, you need:
* a C++14 compiler (e.g. gcc 6.0 or clang 3.9)
* `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
@@ -62,16 +64,17 @@ In any case, you need:
Each plugin usually needs a codec library, which you also need to
install. Check the :doc:`plugins` for details about required libraries
For example, the following installs a fairly complete list of build dependencies on Debian Jessie:
For example, the following installs a fairly complete list of build dependencies on Debian Buster:
.. code-block:: none
apt install g++ \
apt install meson g++ \
libfmt-dev \
libpcre3-dev \
libmad0-dev libmpg123-dev libid3tag0-dev \
libflac-dev libvorbis-dev libopus-dev \
libflac-dev libvorbis-dev libopus-dev libogg-dev \
libadplug-dev libaudiofile-dev libsndfile1-dev libfaad-dev \
libfluidsynth-dev libgme-dev libmikmod2-dev libmodplug-dev \
libfluidsynth-dev libgme-dev libmikmod-dev libmodplug-dev \
libmpcdec-dev libwavpack-dev libwildmidi-dev \
libsidplay2-dev libsidutils-dev libresid-builder-dev \
libavcodec-dev libavformat-dev \
@@ -84,14 +87,16 @@ 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 \
libsystemd-dev \
libgtest-dev \
libboost-dev \
libicu-dev
libicu-dev \
libchromaprint-dev \
libgcrypt20-dev
Now configure the source tree:
@@ -106,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
@@ -137,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:
@@ -163,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
@@ -183,47 +215,6 @@ ABI is the Android ABI to be built, e.g. ":code:`arm64-v8a`".
This downloads various library sources, and then configures and builds :program:`MPD`.
systemd socket activation
-------------------------
Using systemd, you can launch :program:`MPD` on demand when the first client attempts to connect.
:program:`MPD` comes with two systemd unit files: a "service" unit and
a "socket" unit. These will be installed to the directory specified
with :code:`-Dsystemd_system_unit_dir=...`,
e.g. :file:`/lib/systemd/system`.
To enable socket activation, type:
.. code-block:: none
systemctl enable mpd.socket
systemctl start mpd.socket
In this configuration, :program:`MPD` will ignore the :ref:`listener
settings <listeners>` (``bind_to_address`` and ``port``).
systemd user unit
-----------------
You can launch :program:`MPD` as a systemd user unit. These will be
installed to the directory specified with
:code:`-Dsystemd_user_unit_dir=...`,
e.g. :file:`/usr/lib/systemd/user` or
:file:`$HOME/.local/share/systemd/user`.
Once the user unit is installed, you can start and stop :program:`MPD` like any other service:
.. code-block:: none
systemctl --user start mpd
To auto-start :program:`MPD` upon login, type:
.. code-block:: none
systemctl --user enable mpd
Configuration
*************
@@ -258,6 +249,13 @@ another file; the given file name is relative to the current file:
include "other.conf"
You can use :code:`include_optional` instead if you want the included file
to be optional; the directive will be ignored if the file does not exist:
.. code-block:: none
include_optional "may_not_exist.conf"
Configuring the music directory
-------------------------------
@@ -334,6 +332,44 @@ The following table lists the input options valid for all plugins:
More information can be found in the :ref:`input_plugins` reference.
.. _input_cache:
Configuring the Input Cache
^^^^^^^^^^^^^^^^^^^^^^^^^^^
The input cache prefetches queued song files before they are going to
be played. This has several advantages:
- risk of buffer underruns during playback is reduced because this
decouples playback from disk (or network) I/O
- bulk transfers may be faster and more energy efficient than loading
small chunks on-the-fly
- by prefetching several songs at a time, the hard disk can spin down
for longer periods of time
This comes at a cost:
- memory usage
- bulk transfers may reduce the performance of other applications
which also want to access the disk (if the kernel's I/O scheduler
isn't doing its job properly)
To enable the input cache, add an ``input_cache`` block to the
configuration file:
.. code-block:: none
input_cache {
size "1 GB"
}
This allocates a cache of 1 GB. If the cache grows larger than that,
older files will be evicted.
You can flush the cache at any time by sending ``SIGHUP`` to the
:program:`MPD` process, see :ref:`signals`.
Configuring decoder plugins
---------------------------
@@ -405,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.
@@ -417,7 +453,7 @@ The following table lists the audio_output options valid for all plugins:
:ref:`oss_plugin` and PulseAudio :ref:`pulse_plugin`), the
software mixer, the ":samp:`null`" mixer (allows setting the
volume, but with no effect; this can be used as a trick to
implement an external mixer :ref:`external_mixer`) or no mixer
implement an external mixer, see :ref:`external_mixer`) or no mixer
(:samp:`none`). By default, the hardware mixer is used for
devices which support it, and none for the others.
* - **filters "name,...**"
@@ -492,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.
@@ -598,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.
@@ -614,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"
@@ -661,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
^^^^^^^^^^^^^^^^^^^^
@@ -693,7 +745,7 @@ These settings are various limitations to prevent :program:`MPD` from using too
* - **connection_timeout SECONDS**
- If a client does not send any new data in this time period, the connection is closed. Clients waiting in "idle" mode are excluded from this. Default is 60.
* - **max_connections NUMBER**
- This specifies the maximum number of clients that can be connected to :program:`MPD` at the same time. Default is 5.
- This specifies the maximum number of clients that can be connected to :program:`MPD` at the same time. Default is 100.
* - **max_playlist_length NUMBER**
- The maximum number of songs that can be in the playlist. Default is 16384.
* - **max_command_list_size KBYTES**
@@ -712,8 +764,9 @@ Do not change these unless you know what you are doing.
* - Setting
- Description
* - **audio_buffer_size KBYTES**
- Adjust the size of the internal audio buffer. Default is 4096 (4 MiB).
* - **audio_buffer_size SIZE**
- Adjust the size of the internal audio buffer. Default is
:samp:`4 MB` (4 MiB).
Zeroconf
^^^^^^^^
@@ -761,22 +814,24 @@ The :code:`music_directory` setting tells :program:`MPD` to read files from the
The database setting tells :program:`MPD` to pass all database queries on to the :program:`MPD` instance running on the file server (using the proxy plugin).
.. _realtime:
Real-Time Scheduling
--------------------
On Linux, :program:`MPD` attempts to configure real-time scheduling for some threads that benefit from it.
This is only possible you allow :program:`MPD` to do it. This privilege is controlled by :envvar:`RLIMIT_RTPRIO` :envvar:`RLIMIT_RTTIME`. You can configure this privilege with :command:`ulimit` before launching :program:`MPD`:
This is only possible if you allow :program:`MPD` to do it. This privilege is controlled by :envvar:`RLIMIT_RTPRIO` :envvar:`RLIMIT_RTTIME`. You can configure this privilege with :command:`ulimit` before launching :program:`MPD`:
.. code-block:: none
ulimit -HS -r 50; mpd
ulimit -HS -r 40; mpd
Or you can use the :command:`prlimit` program from the util-linux package:
.. code-block:: none
prlimit --rtprio=50 --rttime=unlimited mpd
prlimit --rtprio=40 --rttime=unlimited mpd
The systemd service file shipped with :program:`MPD` comes with this setting.
@@ -794,10 +849,10 @@ You can verify whether the real-time scheduler is active with the ps command:
PID TID CLS RTPRIO COMMAND
16257 16257 TS - mpd
16257 16258 TS - io
16257 16259 FF 50 rtio
16257 16259 FF 40 rtio
16257 16260 TS - player
16257 16261 TS - decoder
16257 16262 FF 50 output:ALSA
16257 16262 FF 40 output:ALSA
16257 16263 IDL 0 update
The CLS column shows the CPU scheduler; TS is the normal scheduler; FF and RR are real-time schedulers. In this example, two threads use the real-time scheduler: the output thread and the rtio (real-time I/O) thread; these two are the important ones. The database update thread uses the idle scheduler ("IDL in ps), which only gets CPU when no other process needs it.
@@ -812,6 +867,89 @@ The CLS column shows the CPU scheduler; TS is the normal scheduler; FF and RR ar
Using MPD
*********
Starting and Stopping MPD
-------------------------
The simplest (but not the best) way to start :program:`MPD` is to
simply type::
mpd
This will start :program:`MPD` as a daemon process (which means it
detaches from your terminal and continues to run in background). To
stop it, send ``SIGTERM`` to the process; if you have configured a
``pid_file``, you can use the ``--kill`` option::
mpd --kill
The best way to manage :program:`MPD` processes is to use a service
manager such as :program:`systemd`.
systemd
^^^^^^^
:program:`MPD` ships with :program:`systemd` service units.
If you have installed :program:`MPD` with your operating system's
package manager, these are probably preinstalled, so you can start and
stop :program:`MPD` this way (like any other service)::
systemctl start mpd
systemctl stop mpd
systemd socket activation
^^^^^^^^^^^^^^^^^^^^^^^^^
Using systemd, you can launch :program:`MPD` on demand when the first client attempts to connect.
:program:`MPD` comes with two systemd unit files: a "service" unit and
a "socket" unit. These will be installed to the directory specified
with :code:`-Dsystemd_system_unit_dir=...`,
e.g. :file:`/lib/systemd/system`.
To enable socket activation, type:
.. code-block:: none
systemctl enable mpd.socket
systemctl start mpd.socket
In this configuration, :program:`MPD` will ignore the :ref:`listener
settings <listeners>` (``bind_to_address`` and ``port``).
systemd user unit
^^^^^^^^^^^^^^^^^
You can launch :program:`MPD` as a systemd user unit. These will be
installed to the directory specified with
:code:`-Dsystemd_user_unit_dir=...`,
e.g. :file:`/usr/lib/systemd/user` or
:file:`$HOME/.local/share/systemd/user`.
Once the user unit is installed, you can start and stop :program:`MPD` like any other service:
.. code-block:: none
systemctl --user start mpd
To auto-start :program:`MPD` upon login, type:
.. code-block:: none
systemctl --user enable mpd
.. _signals:
Signals
-------
:program:`MPD` understands the following UNIX signals:
- ``SIGTERM``, ``SIGINT``: shut down MPD
- ``SIGHUP``: reopen log files (send this after log rotation) and
flush caches (see :ref:`input_cache`)
The client
----------
@@ -933,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.
@@ -951,6 +1097,22 @@ is no way for :program:`MPD` to find out whether the DAC supports
it. DSD to PCM conversion is the fallback if DSD cannot be used
directly.
ICY-MetaData
------------
Some MP3 streams send information about the current song with a
protocol named `"ICY-MetaData"
<http://www.smackfu.com/stuff/programming/shoutcast.html>`_.
:program:`MPD` makes its ``StreamTitle`` value available as ``Title``
tag.
By default, :program:`MPD` assumes this tag is UTF-8-encoded. To tell
:program:`MPD` to assume a different character set, specify it in the
``charset`` URL fragment parameter, e.g.::
mpc add 'http://radio.example.com/stream#charset=cp1251'
Client Hacks
************
@@ -975,7 +1137,7 @@ Sometimes, it is helpful to run :program:`MPD` in a terminal and follow what hap
.. code-block:: none
mpd --stdout --no-daemon --verbose
mpd --stderr --no-daemon --verbose
Support
-------
@@ -983,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.
@@ -1033,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
^^^^^^^^^^^
@@ -1055,7 +1277,7 @@ You can extract the backtrace from a core dump, or by running :program:`MPD` in
.. code-block:: none
gdb --args mpd --stdout --no-daemon --verbose
gdb --args mpd --stderr --no-daemon --verbose
run
As soon as you have reproduced the crash, type ":command:`bt`" on the

View File

@@ -1,11 +1,30 @@
project(
'mpd',
['c', 'cpp'],
version: '0.21.13',
meson_version: '>= 0.49.0',
version: '0.23.2',
meson_version: '>= 0.56.0',
default_options: [
'c_std=c99',
'cpp_std=c++14'
'c_std=c11',
'build.c_std=c11',
'cpp_std=c++17',
'build.cpp_std=c++17',
'warning_level=3',
# 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+',
)
@@ -15,80 +34,99 @@ version_cxx = vcs_tag(input: 'src/GitVersion.cxx', output: 'GitVersion.cxx')
compiler = meson.get_compiler('cpp')
c_compiler = meson.get_compiler('c')
if compiler.get_id() == 'gcc' and compiler.version().version_compare('<6')
warning('Your GCC version is too old. You need at least version 6.')
elif compiler.get_id() == 'clang' and compiler.version().version_compare('<3')
warning('Your clang version is too old. You need at least version 3.')
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('<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.23.1')
configure_file(output: 'Version.h', configuration: version_conf)
conf = configuration_data()
conf.set_quoted('PACKAGE', meson.project_name())
conf.set_quoted('PACKAGE_NAME', meson.project_name())
conf.set_quoted('PACKAGE_VERSION', meson.project_version())
conf.set_quoted('VERSION', meson.project_version())
conf.set_quoted('PROTOCOL_VERSION', '0.21.11')
conf.set_quoted('SYSTEM_CONFIG_FILE_LOCATION', join_paths(get_option('prefix'), get_option('sysconfdir'), 'mpd.conf'))
common_cppflags = [
'-D_GNU_SOURCE',
]
common_cflags = [
]
common_cxxflags = [
test_global_common_flags = [
'-fvisibility=hidden',
]
test_common_flags = [
'-Wall',
'-Wextra',
'-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-subscript',
'-Wextra-semi',
'-Wmismatched-tags',
'-Woverloaded-virtual',
'-Wsign-promo',
'-Wvolatile',
'-Wvirtual-inheritance',
# a vtable without a dtor is just fine
'-Wno-non-virtual-dtor',
# work around bogus GCC7 warning "mangled name for ... will change
# in C++17 because the exception specification is part of a function
# type"
'-Wno-noexcept-type',
# clang specific warning options:
'-Wcomma',
'-Wheader-hygiene',
'-Winconsistent-missing-destructor-override',
]
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_cflags += [
test_global_cxxflags += [
'-ffunction-sections',
'-fdata-sections',
]
test_global_cflags += [
'-ffunction-sections',
'-fdata-sections',
]
@@ -97,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') != ''
@@ -113,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')
@@ -132,28 +201,21 @@ 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_LOCALE_H', compiler.has_header('locale.h'))
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'))
conf.set('HAVE_FNMATCH', compiler.has_function('fnmatch'))
conf.set('HAVE_STRNDUP', compiler.has_function('strndup', prefix: '#define _GNU_SOURCE\n#include <string.h>'))
# Explicitly exclude Windows in this check because
# https://github.com/mesonbuild/meson/issues/3672 (reported in 2018,
# still not fixed in 2020) causes Meson to believe it exists, because
# __builtin_strndup() exists (but strndup() still cannot be used).
conf.set('HAVE_STRNDUP', not is_windows and compiler.has_function('strndup', prefix: '#define _GNU_SOURCE\n#include <string.h>'))
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)
@@ -184,13 +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',
@@ -205,33 +281,31 @@ 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',
'src/decoder/DecoderPrint.cxx',
'src/client/Listener.cxx',
'src/client/Client.cxx',
'src/client/ClientEvent.cxx',
'src/client/ClientExpire.cxx',
'src/client/ClientGlobal.cxx',
'src/client/ClientIdle.cxx',
'src/client/ClientList.cxx',
'src/client/ClientNew.cxx',
'src/client/ClientProcess.cxx',
'src/client/ClientRead.cxx',
'src/client/ClientWrite.cxx',
'src/client/ClientMessage.cxx',
'src/client/ClientSubscribe.cxx',
'src/client/ClientFile.cxx',
'src/client/Config.cxx',
'src/client/Domain.cxx',
'src/client/Event.cxx',
'src/client/Expire.cxx',
'src/client/Idle.cxx',
'src/client/List.cxx',
'src/client/New.cxx',
'src/client/Process.cxx',
'src/client/Read.cxx',
'src/client/Write.cxx',
'src/client/Message.cxx',
'src/client/Subscribe.cxx',
'src/client/File.cxx',
'src/client/Response.cxx',
'src/client/ThreadBackgroundCommand.cxx',
'src/Listen.cxx',
'src/LogInit.cxx',
'src/LogBackend.cxx',
'src/Log.cxx',
'src/ls.cxx',
'src/Instance.cxx',
'src/win32/Win32Main.cxx',
'src/MusicBuffer.cxx',
'src/MusicPipe.cxx',
'src/MusicChunk.cxx',
@@ -273,11 +347,18 @@ sources = [
'src/TagSave.cxx',
'src/TagFile.cxx',
'src/TagStream.cxx',
'src/TagAny.cxx',
'src/TimePrint.cxx',
'src/mixer/Volume.cxx',
'src/PlaylistFile.cxx',
]
if is_windows
sources += [
'src/win32/Win32Main.cxx',
]
endif
if not is_android
sources += [
'src/CommandLine.cxx',
@@ -286,6 +367,7 @@ if not is_android
else
sources += [
'src/android/Context.cxx',
'src/android/AudioManager.cxx',
'src/android/Environment.cxx',
'src/android/LogListener.cxx',
]
@@ -304,9 +386,16 @@ if enable_database
endif
subdir('src/util')
subdir('src/time')
subdir('src/io')
subdir('src/io/uring')
subdir('src/system')
subdir('src/thread')
subdir('src/net')
subdir('src/event')
subdir('src/win32')
subdir('src/apple')
subdir('src/lib/dbus')
subdir('src/lib/icu')
@@ -314,6 +403,7 @@ subdir('src/lib/smbclient')
subdir('src/lib/zlib')
subdir('src/lib/alsa')
subdir('src/lib/chromaprint')
subdir('src/lib/curl')
subdir('src/lib/expat')
subdir('src/lib/ffmpeg')
@@ -321,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')
@@ -328,9 +419,12 @@ subdir('src/lib/systemd')
subdir('src/lib/upnp')
subdir('src/lib/yajl')
subdir('src/lib/crypto')
subdir('src/zeroconf')
subdir('src/fs')
subdir('src/config')
subdir('src/net')
subdir('src/tag')
subdir('src/pcm')
subdir('src/neighbor')
@@ -344,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'
@@ -353,12 +446,19 @@ endif
if sqlite_dep.found()
sources += [
'src/command/StickerCommands.cxx',
'src/sticker/StickerDatabase.cxx',
'src/sticker/StickerPrint.cxx',
'src/sticker/Database.cxx',
'src/sticker/Print.cxx',
'src/sticker/SongSticker.cxx',
]
endif
if chromaprint_dep.found()
sources += [
'src/command/FingerprintCommands.cxx',
'src/lib/chromaprint/DecoderClient.cxx',
]
endif
basic = static_library(
'basic',
'src/ReplayGainInfo.cxx',
@@ -385,8 +485,11 @@ endif
if archive_glue_dep.found()
sources += [
'src/TagArchive.cxx',
'src/db/update/Archive.cxx',
]
if enable_database
sources += ['src/db/update/Archive.cxx']
endif
endif
if is_windows
@@ -449,8 +552,11 @@ mpd = build_target(
sqlite_dep,
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,
)
@@ -486,10 +592,12 @@ install_data(
install_dir: join_paths(get_option('datadir'), 'doc', meson.project_name()),
)
if get_option('documentation')
subdir('doc')
endif
subdir('doc')
if get_option('test')
subdir('test')
endif
if get_option('fuzzer')
subdir('test/fuzzer')
endif

View File

@@ -1,9 +1,10 @@
option('documentation', type: 'boolean', value: false, description: 'Build documentation')
option('test', type: 'boolean', value: false, description: 'Build the unit tests and debug programs')
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('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')
option('daemon', type: 'boolean', value: true, description: 'enable daemonization')
option('systemd', type: 'feature', description: 'systemd support')
@@ -11,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
#
@@ -54,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)')
#
@@ -84,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
@@ -92,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
@@ -123,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')
@@ -162,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')

View File

@@ -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)

View File

@@ -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))

86
python/build/cmake.py Normal file
View File

@@ -0,0 +1,86 @@
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_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',
'-GNinja',
] + cross_args + args
subprocess.check_call(configure, env=toolchain.env, cwd=build)
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_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):
build = self.configure(toolchain)
subprocess.check_call(['ninja', 'install'],
cwd=build, env=toolchain.env)

View File

@@ -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
View 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)

View File

@@ -4,42 +4,33 @@ from os.path import abspath
from build.project import Project
from build.zlib import ZlibProject
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.16.tar.xz',
'fa6bdab67c0e0490302b38f00c27b4959735c3ec8aef7a88327adb1407654464',
'https://www.musicpd.org/download/libmpdclient/2/libmpdclient-2.19.tar.xz',
'158aad4c2278ab08e76a3f2b0166c99b39fae00ee17231bd225c5a36e977a189',
'lib/libmpdclient.a',
)
libogg = AutotoolsProject(
'http://downloads.xiph.org/releases/ogg/libogg-1.3.3.tar.xz',
'4f3fc6178a533d392064f14776b23c397ed4b9f48f5de297aba73b643f955c08',
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.6.tar.xz',
'af00bb5a784e7c9e69f56823de4637c350643deedaf333d0fa86ecdba6fcb415',
'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.tar.gz',
'4f3d69aefdf2dbaf9825408e452a8a414ffc60494c70633560700398820dc550',
'https://archive.mozilla.org/pub/opus/opus-1.3.1.tar.gz',
'65b58e1e25b2a114157014736a3d9dfeaad8d41be1c8179866f144a2fb44ff9d',
'lib/libopus.a',
[
'--disable-shared', '--enable-static',
@@ -52,8 +43,8 @@ opus = AutotoolsProject(
)
flac = AutotoolsProject(
'http://downloads.xiph.org/releases/flac/flac-1.3.2.tar.xz',
'91cfc3ed61dc40f47f050a109b08610667d73477af6ef36dcad31c31a4a8d53f',
'http://downloads.xiph.org/releases/flac/flac-1.3.3.tar.xz',
'213e82bd716c9de6db2f98bcadbc4c24c7e2efe8c75939a1a84e28539c4e1748',
'lib/libFLAC.a',
[
'--disable-shared', '--enable-static',
@@ -111,9 +102,53 @@ liblame = AutotoolsProject(
],
)
libmodplug = AutotoolsProject(
'https://downloads.sourceforge.net/modplug-xmms/libmodplug/0.8.9.0/libmodplug-0.8.9.0.tar.gz',
'457ca5a6c179656d66c01505c0d95fafaead4329b9dbaa0f997d00a3508ad9de',
'lib/libmodplug.a',
[
'--disable-shared', '--enable-static',
],
)
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.4',
'6f267c8d331e9859906837e2c197093fddec31829d2ebf7b958cf6b7ae935430',
'lib/libWildMidi.a',
[
'-DBUILD_SHARED_LIBS=OFF',
'-DWANT_PLAYER=OFF',
'-DWANT_STATIC=ON',
],
base='wildmidi-wildmidi-0.4.4',
name='wildmidi',
version='0.4.4',
)
gme = CmakeProject(
'https://bitbucket.org/mpyne/game-music-emu/downloads/game-music-emu-0.6.3.tar.xz',
'aba34e53ef0ec6a34b58b84e28bf8cfbccee6585cebca25333604c35db3e051d',
'lib/libgme.a',
[
'-DBUILD_SHARED_LIBS=OFF',
'-DENABLE_UBSAN=OFF',
'-DZLIB_INCLUDE_DIR=OFF',
'-DSDL2_DIR=OFF',
],
)
ffmpeg = FfmpegProject(
'http://ffmpeg.org/releases/ffmpeg-4.1.3.tar.xz',
'0c3020452880581a8face91595b239198078645e7d7184273b8bcc7758beb63d',
'http://ffmpeg.org/releases/ffmpeg-4.4.tar.xz',
'06b10a183ce5371f915c6bb15b7b1fffbe046e8275099c96affc29e17645d909',
'lib/libavcodec.a',
[
'--disable-shared', '--enable-static',
@@ -340,38 +375,45 @@ ffmpeg = FfmpegProject(
],
)
curl = AutotoolsProject(
'http://curl.haxx.se/download/curl-7.64.1.tar.xz',
'9252332a7f871ce37bfa7f78bdd0a0e3924d8187cc27cb57c76c9474a7168fb3',
'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',
'--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_6/expat-2.2.6.tar.bz2',
'17b43c2716d521369f82fc2dc70f359860e90fa440bea65b3b85f0b246ea81f2',
'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(
@@ -388,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(
'http://downloads.sourceforge.net/project/boost/boost/1.70.0/boost_1_70_0.tar.bz2',
'430ae8354789de4fd19ee52f3b1f739e1fba576f0aded0897c3c2bc00fb38778',
'https://boostorg.jfrog.io/artifactory/main/release/1.77.0/source/boost_1_77_0.tar.bz2',
'fc9f85fc030e233142908241af7a846e60630aa7388de9a5fafb1f3a26840854',
'include/boost/version.hpp',
)

View File

@@ -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))

View File

@@ -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',
@@ -91,7 +92,12 @@ def configure(toolchain, src, build, args=()):
'--cross-file', cross_file,
] + args
subprocess.check_call(configure, env=toolchain.env)
env = toolchain.env.copy()
# Meson 0.54 requires the BOOST_ROOT environment variable
env['BOOST_ROOT'] = toolchain.install_prefix
subprocess.check_call(configure, env=env)
class MesonProject(Project):
def __init__(self, url, md5, installed, configure_args=[],
@@ -105,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
View 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)

View File

@@ -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)

View File

@@ -7,5 +7,11 @@ def untar(tarball_path, parent_path, base):
except FileNotFoundError:
pass
os.makedirs(parent_path, exist_ok=True)
subprocess.check_call(['/bin/tar', 'xfC', tarball_path, parent_path])
try:
subprocess.check_call(['/bin/tar', 'xfC', tarball_path, parent_path])
except FileNotFoundError:
import tarfile
tar = tarfile.open(tarball_path)
tar.extractall(path=parent_path)
tar.close()
return path

View File

@@ -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

View File

@@ -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',

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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
@@ -95,7 +95,7 @@ public:
constexpr double ToDoubleS() const {
return double(count()) / 1000.;
};
}
constexpr bool IsZero() const {
return count() == 0;
@@ -199,7 +199,7 @@ public:
constexpr double ToDoubleS() const {
return double(count()) / 1000.;
};
}
constexpr bool IsZero() const {
return count() == 0;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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,15 +33,20 @@
#include "playlist/PlaylistRegistry.hxx"
#include "playlist/PlaylistPlugin.hxx"
#include "fs/AllocatedPath.hxx"
#include "fs/NarrowPath.hxx"
#include "fs/Traits.hxx"
#include "fs/FileSystem.hxx"
#include "fs/StandardDirectory.hxx"
#include "system/Error.hxx"
#include "util/Macros.hxx"
#include "util/RuntimeError.hxx"
#include "event/Features.h"
#include "io/uring/Features.h"
#include "util/Domain.hxx"
#include "util/OptionDef.hxx"
#include "util/OptionParser.hxx"
#include "Version.h"
#ifdef _WIN32
#include "system/Error.hxx"
#endif
#ifdef ENABLE_DATABASE
#include "db/Registry.hxx"
@@ -55,6 +60,7 @@
#include "neighbor/NeighborPlugin.hxx"
#endif
#include "encoder/Features.h"
#ifdef ENABLE_ENCODER
#include "encoder/EncoderList.hxx"
#include "encoder/EncoderPlugin.hxx"
@@ -65,9 +71,6 @@
#include "archive/ArchivePlugin.hxx"
#endif
#include <stdio.h>
#include <stdlib.h>
namespace {
#ifdef _WIN32
constexpr auto CONFIG_FILE_LOCATION = Path::FromFS(PATH_LITERAL("mpd\\mpd.conf"));
@@ -77,7 +80,7 @@ constexpr auto USER_CONFIG_FILE_LOCATION1 = Path::FromFS(PATH_LITERAL(".mpdconf"
constexpr auto USER_CONFIG_FILE_LOCATION2 = Path::FromFS(PATH_LITERAL(".mpd/mpd.conf"));
constexpr auto USER_CONFIG_FILE_LOCATION_XDG = Path::FromFS(PATH_LITERAL("mpd/mpd.conf"));
#endif
}
} // namespace
enum Option {
OPTION_KILL,
@@ -105,13 +108,13 @@ static constexpr OptionDef option_defs[] = {
static constexpr Domain cmdline_domain("cmdline");
gcc_noreturn
static void version(void)
[[noreturn]]
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);
@@ -145,15 +148,19 @@ static void version(void)
"Decoders plugins:\n");
decoder_plugins_for_each([](const DecoderPlugin &plugin){
printf(" [%s]", plugin.name);
printf(" [%s]", plugin.name);
const char *const*suffixes = plugin.suffixes;
if (suffixes != nullptr)
for (; *suffixes != nullptr; ++suffixes)
printf(" %s", *suffixes);
const char *const*suffixes = plugin.suffixes;
if (suffixes != nullptr)
for (; *suffixes != nullptr; ++suffixes)
printf(" %s", *suffixes);
printf("\n");
});
if (plugin.protocols != nullptr)
for (const auto &i : plugin.protocols())
printf(" %s", i.c_str());
printf("\n");
});
printf("\n"
"Filters:\n"
@@ -202,6 +209,9 @@ static void version(void)
"\n"
"Input plugins:\n"
" file"
#ifdef HAVE_URING
" io_uring"
#endif
#ifdef ENABLE_ARCHIVE
" archive"
#endif
@@ -255,7 +265,7 @@ static void version(void)
#endif
"\n");
exit(EXIT_SUCCESS);
std::exit(EXIT_SUCCESS);
}
static void PrintOption(const OptionDef &opt)
@@ -271,8 +281,8 @@ static void PrintOption(const OptionDef &opt)
opt.GetDescription());
}
gcc_noreturn
static void help(void)
[[noreturn]]
static void help()
{
printf("Usage:\n"
" mpd [OPTION...] [path/to/mpd.conf]\n"
@@ -282,10 +292,10 @@ static void help(void)
"Options:\n");
for (const auto &i : option_defs)
if(i.HasDescription() == true) // hide hidden options from help print
if(i.HasDescription()) // hide hidden options from help print
PrintOption(i);
exit(EXIT_SUCCESS);
std::exit(EXIT_SUCCESS);
}
class ConfigLoader
@@ -296,7 +306,7 @@ public:
explicit ConfigLoader(ConfigData &_config) noexcept
:config(_config) {}
bool TryFile(const Path path);
bool TryFile(Path path);
bool TryFile(const AllocatedPath &base_path, Path path);
};
@@ -380,17 +390,7 @@ ParseCommandLine(int argc, char **argv, struct options &options,
if (config_file != nullptr) {
/* use specified configuration file */
#ifdef _UNICODE
wchar_t buffer[MAX_PATH];
auto result = MultiByteToWideChar(CP_ACP, 0, config_file, -1,
buffer, ARRAY_SIZE(buffer));
if (result <= 0)
throw MakeLastError("MultiByteToWideChar() failed");
ReadConfigFile(config, Path::FromFS(buffer));
#else
ReadConfigFile(config, Path::FromFS(config_file));
#endif
ReadConfigFile(config, FromNarrowPath(config_file));
return;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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,4 +19,4 @@
#include "GitVersion.hxx"
char GIT_VERSION[] = "@VCS_TAG@";
const char GIT_VERSION[] = "@VCS_TAG@";

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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,6 +20,6 @@
#ifndef MPD_GIT_VERSION_HXX
#define MPD_GIT_VERSION_HXX
extern char GIT_VERSION[];
extern const char GIT_VERSION[];
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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
@@ -18,16 +18,24 @@
*/
#include "IcyMetaDataParser.hxx"
#include "tag/Tag.hxx"
#include "tag/Builder.hxx"
#include "util/Domain.hxx"
#include "util/AllocatedString.hxx"
#include "util/StringView.hxx"
#include "Log.hxx"
#include <assert.h>
#include <algorithm>
#include <cassert>
#include <string.h>
static constexpr Domain icy_metadata_domain("icy_metadata");
#ifdef HAVE_ICU_CONVERTER
void
IcyMetaDataParser::SetCharset(const char *charset)
{
icu_converter = IcuConverter::Create(charset);
}
#endif
void
IcyMetaDataParser::Reset() noexcept
@@ -65,29 +73,40 @@ IcyMetaDataParser::Data(size_t length) noexcept
}
static void
icy_add_item(TagBuilder &tag, TagType type, const char *value) noexcept
icy_add_item(TagBuilder &tag, TagType type, StringView value) noexcept
{
size_t length = strlen(value);
if (length >= 2 && value[0] == '\'' && value[length - 1] == '\'') {
if (value.size >= 2 && value.front() == '\'' && value.back() == '\'') {
/* strip the single quotes */
++value;
length -= 2;
++value.data;
value.size -= 2;
}
if (length > 0)
tag.AddItem(type, {value, length});
if (value.size > 0)
tag.AddItem(type, value);
}
static void
icy_parse_tag_item(TagBuilder &tag,
#ifdef HAVE_ICU_CONVERTER
const IcuConverter *icu_converter,
#endif
const char *name, const char *value) noexcept
{
if (strcmp(name, "StreamTitle") == 0)
if (strcmp(name, "StreamTitle") == 0) {
#ifdef HAVE_ICU_CONVERTER
if (icu_converter != nullptr) {
try {
icy_add_item(tag, TAG_TITLE,
icu_converter->ToUTF8(value).c_str());
} catch (...) {
}
return;
}
#endif
icy_add_item(tag, TAG_TITLE, value);
else
FormatDebug(icy_metadata_domain,
"unknown icy-tag: '%s'", name);
}
}
/**
@@ -116,7 +135,11 @@ find_end_quote(char *p, char *const end) noexcept
}
static std::unique_ptr<Tag>
icy_parse_tag(char *p, char *const end) noexcept
icy_parse_tag(
#ifdef HAVE_ICU_CONVERTER
const IcuConverter *icu_converter,
#endif
char *p, char *const end) noexcept
{
assert(p != nullptr);
assert(end != nullptr);
@@ -153,7 +176,11 @@ icy_parse_tag(char *p, char *const end) noexcept
*quote = 0;
p = quote + 1;
icy_parse_tag_item(tag, name, value);
icy_parse_tag_item(tag,
#ifdef HAVE_ICU_CONVERTER
icu_converter,
#endif
name, value);
char *semicolon = std::find(p, end, ';');
if (semicolon == end)
@@ -167,7 +194,7 @@ icy_parse_tag(char *p, char *const end) noexcept
size_t
IcyMetaDataParser::Meta(const void *data, size_t length) noexcept
{
const unsigned char *p = (const unsigned char *)data;
const auto *p = (const unsigned char *)data;
assert(IsDefined());
assert(data_rest == 0);
@@ -208,7 +235,11 @@ IcyMetaDataParser::Meta(const void *data, size_t length) noexcept
if (meta_position == meta_size) {
/* parse */
tag = icy_parse_tag(meta_data, meta_data + meta_size);
tag = icy_parse_tag(
#ifdef HAVE_ICU_CONVERTER
icu_converter.get(),
#endif
meta_data, meta_data + meta_size);
delete[] meta_data;
/* change back to normal data mode */
@@ -223,7 +254,7 @@ IcyMetaDataParser::Meta(const void *data, size_t length) noexcept
size_t
IcyMetaDataParser::ParseInPlace(void *data, size_t length) noexcept
{
uint8_t *const dest0 = (uint8_t *)data;
auto *const dest0 = (uint8_t *)data;
uint8_t *dest = dest0;
const uint8_t *src = dest0;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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,18 +20,23 @@
#ifndef MPD_ICY_META_DATA_PARSER_HXX
#define MPD_ICY_META_DATA_PARSER_HXX
#include "lib/icu/Converter.hxx"
#include "tag/Tag.hxx"
#include "config.h"
#include <cstddef>
#include <memory>
#include <stddef.h>
class IcyMetaDataParser {
size_t data_size = 0, data_rest;
size_t meta_size, meta_position;
char *meta_data;
#ifdef HAVE_ICU_CONVERTER
std::unique_ptr<IcuConverter> icu_converter;
#endif
std::unique_ptr<Tag> tag;
public:
@@ -39,6 +44,13 @@ public:
Reset();
}
#ifdef HAVE_ICU_CONVERTER
/**
* Throws on error.
*/
void SetCharset(const char *charset);
#endif
/**
* Initialize an enabled icy_metadata object with the specified
* data_size (from the icy-metaint HTTP response header).

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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
@@ -26,12 +26,12 @@
#include "Main.hxx"
#include "Instance.hxx"
#include <assert.h>
#include <cassert>
void
idle_add(unsigned flags)
{
assert(flags != 0);
instance->EmitIdle(flags);
global_instance->EmitIdle(flags);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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,9 +25,9 @@
#include "IdleFlags.hxx"
#include "util/ASCII.hxx"
#include <assert.h>
#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*

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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,12 +20,15 @@
#include "config.h"
#include "Instance.hxx"
#include "Partition.hxx"
#include "Idle.hxx"
#include "IdleFlags.hxx"
#include "StateFile.hxx"
#include "Stats.hxx"
#include "client/List.hxx"
#include "input/cache/Manager.hxx"
#ifdef ENABLE_CURL
#include "RemoteTagCache.hxx"
#include "util/UriUtil.hxx"
#include "util/UriExtract.hxx"
#endif
#ifdef ENABLE_DATABASE
@@ -34,14 +37,20 @@
#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
#ifdef ENABLE_SQLITE
#include "sticker/StickerDatabase.hxx"
#include "sticker/Database.hxx"
#include "sticker/SongSticker.hxx"
#endif
#endif
#include <exception>
Instance::Instance()
:rtio_thread(true),
#ifdef ENABLE_SYSTEMD_DAEMON
@@ -65,6 +74,13 @@ Instance::~Instance() noexcept
#endif
}
void
Instance::OnStateModified() noexcept
{
if (state_file)
state_file->CheckModified();
}
Partition *
Instance::FindPartition(const char *name) noexcept
{
@@ -75,6 +91,20 @@ Instance::FindPartition(const char *name) noexcept
return nullptr;
}
void
Instance::DeletePartition(Partition &partition) noexcept
{
// TODO: use boost::intrusive::list to avoid this loop
for (auto i = partitions.begin();; ++i) {
assert(i != partitions.end());
if (&*i == &partition) {
partitions.erase(i);
break;
}
}
}
#ifdef ENABLE_DATABASE
const Database &
@@ -88,7 +118,7 @@ Instance::GetDatabaseOrThrow() const
}
void
Instance::OnDatabaseModified()
Instance::OnDatabaseModified() noexcept
{
assert(database != nullptr);
@@ -101,15 +131,15 @@ Instance::OnDatabaseModified()
}
void
Instance::OnDatabaseSongRemoved(const char *uri)
Instance::OnDatabaseSongRemoved(const char *uri) noexcept
{
assert(database != nullptr);
#ifdef ENABLE_SQLITE
/* if the song has a sticker, remove it */
if (sticker_enabled()) {
if (HasStickerDatabase()) {
try {
sticker_song_delete(uri);
sticker_song_delete(*sticker_database, uri);
} catch (...) {
}
}
@@ -124,17 +154,15 @@ Instance::OnDatabaseSongRemoved(const char *uri)
#ifdef ENABLE_NEIGHBOR_PLUGINS
void
Instance::FoundNeighbor(gcc_unused const NeighborInfo &info) noexcept
Instance::FoundNeighbor([[maybe_unused]] const NeighborInfo &info) noexcept
{
for (auto &partition : partitions)
partition.EmitIdle(IDLE_NEIGHBOR);
EmitIdle(IDLE_NEIGHBOR);
}
void
Instance::LostNeighbor(gcc_unused const NeighborInfo &info) noexcept
Instance::LostNeighbor([[maybe_unused]] const NeighborInfo &info) noexcept
{
for (auto &partition : partitions)
partition.EmitIdle(IDLE_NEIGHBOR);
EmitIdle(IDLE_NEIGHBOR);
}
#endif
@@ -166,3 +194,18 @@ Instance::OnRemoteTag(const char *uri, const Tag &tag) noexcept
}
#endif
void
Instance::OnIdle(unsigned flags) noexcept
{
/* broadcast to all partitions */
for (auto &partition : partitions)
partition.EmitIdle(flags);
}
void
Instance::FlushCaches() noexcept
{
if (input_cache)
input_cache->Flush();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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>
@@ -53,6 +55,8 @@ class ClientList;
struct Partition;
class StateFile;
class RemoteTagCache;
class StickerDatabase;
class InputCacheManager;
/**
* A utility class which, when used as the first base class, ensures
@@ -97,10 +101,16 @@ struct Instance final
Systemd::Watchdog systemd_watchdog;
#endif
std::unique_ptr<InputCacheManager> input_cache;
/**
* Monitor for global idle events to be broadcasted to all
* partitions.
*/
MaskMonitor idle_monitor;
#ifdef ENABLE_NEIGHBOR_PLUGINS
NeighborGlue *neighbors;
std::unique_ptr<NeighborGlue> neighbors;
#endif
#ifdef ENABLE_DATABASE
@@ -113,17 +123,25 @@ struct Instance final
Storage *storage = nullptr;
UpdateService *update = nullptr;
#ifdef ENABLE_INOTIFY
std::unique_ptr<InotifyUpdate> inotify_update;
#endif
#endif
#ifdef ENABLE_CURL
std::unique_ptr<RemoteTagCache> remote_tag_cache;
#endif
ClientList *client_list;
std::unique_ptr<ClientList> client_list;
std::list<Partition> partitions;
StateFile *state_file = nullptr;
std::unique_ptr<StateFile> state_file;
#ifdef ENABLE_SQLITE
std::unique_ptr<StickerDatabase> sticker_database;
#endif
Instance();
~Instance() noexcept;
@@ -131,21 +149,36 @@ struct Instance final
/**
* Wrapper for EventLoop::Break(). Call to initiate shutdown.
*/
void Break() {
void Break() noexcept {
event_loop.Break();
}
void EmitIdle(unsigned mask) {
/**
* Emit an "idle" event to all clients of all partitions.
*
* This method can be called from any thread.
*/
void EmitIdle(unsigned mask) noexcept {
idle_monitor.OrMask(mask);
}
/**
* Notify the #Instance that the state has been modified, and
* the #StateFile may need to be saved.
*
* This method must be called from the main thread.
*/
void OnStateModified() noexcept;
/**
* 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;
void BeginShutdownPartitions() noexcept;
#ifdef ENABLE_DATABASE
@@ -154,7 +187,7 @@ struct Instance final
* if this MPD configuration has no database (no
* music_directory was configured).
*/
Database *GetDatabase() {
Database *GetDatabase() noexcept {
return database.get();
}
@@ -166,6 +199,12 @@ struct Instance final
const Database &GetDatabaseOrThrow() const;
#endif
#ifdef ENABLE_SQLITE
bool HasStickerDatabase() const noexcept {
return sticker_database != nullptr;
}
#endif
void BeginShutdownUpdate() noexcept;
#ifdef ENABLE_CURL
@@ -176,10 +215,13 @@ struct Instance final
}
#endif
void FlushCaches() noexcept;
private:
#ifdef ENABLE_DATABASE
void OnDatabaseModified() override;
void OnDatabaseSongRemoved(const char *uri) override;
/* virtual methods from class DatabaseListener */
void OnDatabaseModified() noexcept override;
void OnDatabaseSongRemoved(const char *uri) noexcept override;
#endif
#ifdef ENABLE_NEIGHBOR_PLUGINS
@@ -194,7 +236,7 @@ private:
#endif
/* callback for #idle_monitor */
void OnIdle(unsigned mask);
void OnIdle(unsigned mask) noexcept;
};
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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,17 +25,18 @@
#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>
#include <string.h>
#include <assert.h>
#ifdef ENABLE_SYSTEMD_DAEMON
#include <systemd/sd-daemon.h>
@@ -43,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
@@ -100,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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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,13 +22,16 @@
#include "client/Client.hxx"
#include "fs/AllocatedPath.hxx"
#include "ls.hxx"
#include "util/UriUtil.hxx"
#include "storage/Registry.hxx"
#include "util/ASCII.hxx"
#include "util/UriExtract.hxx"
#ifdef ENABLE_DATABASE
#include "storage/StorageInterface.hxx"
#endif
#include <stdexcept>
static LocatedUri
LocateFileUri(const char *uri, const Client *client
#ifdef ENABLE_DATABASE
@@ -40,11 +43,13 @@ LocateFileUri(const char *uri, const Client *client
#ifdef ENABLE_DATABASE
if (storage != nullptr) {
const char *suffix = storage->MapToRelativeUTF8(uri);
if (suffix != nullptr)
const auto suffix = storage->MapToRelativeUTF8(uri);
if (suffix.data() != nullptr)
/* this path was relative to the music
directory */
return LocatedUri(LocatedUri::Type::RELATIVE, suffix);
// TODO: don't use suffix.data() (ok for now because we know it's null-terminated)
return LocatedUri(LocatedUri::Type::RELATIVE,
suffix.data());
}
#endif
@@ -63,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:
@@ -78,10 +87,16 @@ LocateAbsoluteUri(UriPluginKind kind, const char *uri
#ifdef ENABLE_DATABASE
if (storage != nullptr) {
const char *suffix = storage->MapToRelativeUTF8(uri);
if (suffix != nullptr)
return LocatedUri(LocatedUri::Type::RELATIVE, suffix);
const auto suffix = storage->MapToRelativeUTF8(uri);
if (suffix.data() != nullptr)
// TODO: don't use suffix.data() (ok for now because we know it's null-terminated)
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);
@@ -99,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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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,7 +21,6 @@
#define MPD_LOCATE_URI_HXX
#include "config.h"
#include "util/Compiler.h"
#include "fs/AllocatedPath.hxx"
#ifdef _WIN32

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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,197 +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 <exception>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fmt/format.h>
static constexpr Domain exception_domain("exception");
void
LogFormatV(const Domain &domain, LogLevel level,
const char *fmt, 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(domain, level, 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
LogFormat(const Domain &domain, LogLevel level, const char *fmt, ...) noexcept
Log(LogLevel level, const std::exception_ptr &ep) noexcept
{
va_list ap;
va_start(ap, fmt);
LogFormatV(domain, level, fmt, ap);
va_end(ap);
Log(level, exception_domain, GetFullMessage(ep));
}
void
FormatDebug(const Domain &domain, const char *fmt, ...) noexcept
Log(LogLevel level, const std::exception_ptr &ep, const char *msg) noexcept
{
va_list ap;
va_start(ap, fmt);
LogFormatV(domain, LogLevel::DEBUG, fmt, ap);
va_end(ap);
}
void
FormatInfo(const Domain &domain, const char *fmt, ...) noexcept
{
va_list ap;
va_start(ap, fmt);
LogFormatV(domain, LogLevel::INFO, fmt, ap);
va_end(ap);
}
void
FormatDefault(const Domain &domain, const char *fmt, ...) noexcept
{
va_list ap;
va_start(ap, fmt);
LogFormatV(domain, LogLevel::DEFAULT, fmt, ap);
va_end(ap);
}
void
FormatWarning(const Domain &domain, const char *fmt, ...) noexcept
{
va_list ap;
va_start(ap, fmt);
LogFormatV(domain, LogLevel::WARNING, fmt, ap);
va_end(ap);
}
void
FormatError(const Domain &domain, const char *fmt, ...) noexcept
{
va_list ap;
va_start(ap, fmt);
LogFormatV(domain, LogLevel::ERROR, fmt, ap);
va_end(ap);
}
void
LogError(const std::exception &e) noexcept
{
Log(exception_domain, LogLevel::ERROR, e.what());
try {
std::rethrow_if_nested(e);
} catch (const std::exception &nested) {
LogError(nested, "nested");
} catch (...) {
Log(exception_domain, LogLevel::ERROR,
"Unrecognized nested exception");
}
}
void
LogError(const std::exception &e, const char *msg) noexcept
{
FormatError(exception_domain, "%s: %s", msg, e.what());
try {
std::rethrow_if_nested(e);
} catch (const std::exception &nested) {
LogError(nested);
} catch (...) {
Log(exception_domain, LogLevel::ERROR,
"Unrecognized nested exception");
}
}
void
FormatError(const std::exception &e, const char *fmt, ...) noexcept
{
char msg[1024];
va_list ap;
va_start(ap, fmt);
vsnprintf(msg, sizeof(msg), fmt, ap);
va_end(ap);
LogError(e, msg);
}
void
LogError(const std::exception_ptr &ep) noexcept
{
try {
std::rethrow_exception(ep);
} catch (const std::exception &e) {
LogError(e);
} catch (...) {
Log(exception_domain, LogLevel::ERROR,
"Unrecognized exception");
}
}
void
LogError(const std::exception_ptr &ep, const char *msg) noexcept
{
try {
std::rethrow_exception(ep);
} catch (const std::exception &e) {
LogError(e, msg);
} catch (...) {
FormatError(exception_domain,
"%s: Unrecognized exception", msg);
}
}
void
FormatError(const std::exception_ptr &ep, const char *fmt, ...) noexcept
{
char msg[1024];
va_list ap;
va_start(ap, fmt);
vsnprintf(msg, sizeof(msg), fmt, ap);
va_end(ap);
LogError(ep, msg);
}
void
LogErrno(const Domain &domain, int e, const char *msg) noexcept
{
LogFormat(domain, LogLevel::ERROR, "%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, 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
{
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;
va_list ap;
va_start(ap, fmt);
FormatErrnoV(domain, e, fmt, ap);
va_end(ap);
LogFmt(level, exception_domain, "{}: {}", msg, ep);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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,101 +21,127 @@
#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(const Domain &domain, LogLevel level, const char *msg) noexcept;
Log(LogLevel level, const Domain &domain, std::string_view msg) noexcept;
gcc_printf(3,4)
void
LogFormat(const Domain &domain, LogLevel level, const char *fmt, ...) noexcept;
LogVFmt(LogLevel level, const Domain &domain,
fmt::string_view format_str, fmt::format_args args) noexcept;
template<typename S, typename... Args>
void
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
}
template<typename S, typename... Args>
void
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;
void
Log(LogLevel level, const std::exception_ptr &ep, const char *msg) noexcept;
static inline void
LogDebug(const Domain &domain, const char *msg) noexcept
{
Log(domain, LogLevel::DEBUG, msg);
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(domain, LogLevel::INFO, msg);
Log(LogLevel::INFO, domain, msg);
}
gcc_printf(2,3)
void
FormatInfo(const Domain &domain, const char *fmt, ...) noexcept;
static inline void
LogDefault(const Domain &domain, const char *msg) noexcept
LogNotice(const Domain &domain, const char *msg) noexcept
{
Log(domain, LogLevel::DEFAULT, msg);
Log(LogLevel::NOTICE, domain, msg);
}
gcc_printf(2,3)
void
FormatDefault(const Domain &domain, const char *fmt, ...) noexcept;
static inline void
LogWarning(const Domain &domain, const char *msg) noexcept
{
Log(domain, LogLevel::WARNING, msg);
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(domain, LogLevel::ERROR, msg);
Log(LogLevel::ERROR, domain, msg);
}
void
LogError(const std::exception &e) noexcept;
inline void
LogError(const std::exception_ptr &ep) noexcept
{
Log(LogLevel::ERROR, ep);
}
void
LogError(const std::exception &e, const char *msg) noexcept;
gcc_printf(2,3)
void
FormatError(const std::exception &e, const char *fmt, ...) noexcept;
void
LogError(const std::exception_ptr &ep) noexcept;
void
LogError(const std::exception_ptr &ep, const char *msg) noexcept;
gcc_printf(2,3)
void
FormatError(const std::exception_ptr &ep, const char *fmt, ...) noexcept;
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;
inline void
LogError(const std::exception_ptr &ep, const char *msg) noexcept
{
Log(LogLevel::ERROR, ep, msg);
}
#endif /* LOG_H */

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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,9 +21,11 @@
#include "Log.hxx"
#include "util/Domain.hxx"
#include "util/StringStrip.hxx"
#include "Version.h"
#include "config.h"
#include <assert.h>
#include <cassert>
#include <stdio.h>
#include <string.h>
#include <time.h>
@@ -45,7 +47,7 @@ ToAndroidLogLevel(LogLevel log_level) noexcept
return ANDROID_LOG_DEBUG;
case LogLevel::INFO:
case LogLevel::DEFAULT:
case LogLevel::NOTICE:
return ANDROID_LOG_INFO;
case LogLevel::WARNING:
@@ -61,7 +63,7 @@ ToAndroidLogLevel(LogLevel log_level) noexcept
#else
static LogLevel log_threshold = LogLevel::INFO;
static LogLevel log_threshold = LogLevel::NOTICE;
static bool enable_timestamp;
@@ -101,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
@@ -120,7 +121,7 @@ ToSysLogLevel(LogLevel log_level) noexcept
case LogLevel::INFO:
return LOG_INFO;
case LogLevel::DEFAULT:
case LogLevel::NOTICE:
return LOG_NOTICE;
case LogLevel::WARNING:
@@ -135,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
@@ -159,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
@@ -176,14 +177,20 @@ FileLog(const Domain &domain, const char *message) noexcept
#endif /* !ANDROID */
void
Log(const Domain &domain, LogLevel level, 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)

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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
@@ -28,24 +28,24 @@
#include "fs/FileSystem.hxx"
#include "util/Domain.hxx"
#include "util/RuntimeError.hxx"
#include "util/StringAPI.hxx"
#include "system/Error.hxx"
#include <cassert>
#ifdef ENABLE_SYSTEMD_DAEMON
#include <systemd/sd-daemon.h>
#endif
#include <assert.h>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#define LOG_LEVEL_SECURE LogLevel::INFO
#define LOG_DATE_BUF_SIZE 16
#define LOG_DATE_LEN (LOG_DATE_BUF_SIZE - 1)
gcc_unused
[[maybe_unused]]
static constexpr Domain log_domain("log");
#ifndef ANDROID
@@ -63,7 +63,7 @@ static void redirect_logs(int fd)
}
static int
open_log_file(void)
open_log_file()
{
assert(!out_path.IsNull());
@@ -93,17 +93,24 @@ log_init_file(int line)
}
static inline LogLevel
parse_log_level(const char *value, int line)
parse_log_level(const char *value)
{
if (0 == strcmp(value, "default"))
return LogLevel::DEFAULT;
if (0 == strcmp(value, "secure"))
return LOG_LEVEL_SECURE;
else if (0 == strcmp(value, "verbose"))
if (StringIsEqual(value, "notice") ||
/* deprecated name: */
StringIsEqual(value, "default"))
return LogLevel::NOTICE;
else if (StringIsEqual(value, "info") ||
/* deprecated since MPD 0.22: */
StringIsEqual(value, "secure"))
return LogLevel::INFO;
else if (StringIsEqual(value, "verbose"))
return LogLevel::DEBUG;
else if (StringIsEqual(value, "warning"))
return LogLevel::WARNING;
else if (StringIsEqual(value, "error"))
return LogLevel::ERROR;
else
throw FormatRuntimeError("unknown log level \"%s\" at line %d",
value, line);
throw FormatRuntimeError("unknown log level \"%s\"", value);
}
#endif
@@ -132,9 +139,12 @@ log_init(const ConfigData &config, bool verbose, bool use_stdout)
#else
if (verbose)
SetLogThreshold(LogLevel::DEBUG);
else if (const auto &param = config.GetParam(ConfigOption::LOG_LEVEL))
SetLogThreshold(parse_log_level(param->value.c_str(),
param->line));
else
SetLogThreshold(config.With(ConfigOption::LOG_LEVEL, [](const char *s){
return s != nullptr
? parse_log_level(s)
: LogLevel::NOTICE;
}));
if (use_stdout) {
out_fd = STDOUT_FILENO;
@@ -157,7 +167,7 @@ log_init(const ConfigData &config, bool verbose, bool use_stdout)
throw std::runtime_error("config parameter 'log_file' not found");
#endif
#ifdef HAVE_SYSLOG
} else if (strcmp(param->value.c_str(), "syslog") == 0) {
} else if (StringIsEqual(param->value.c_str(), "syslog")) {
LogInitSysLog();
#endif
} else {
@@ -224,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
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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
@@ -42,7 +42,7 @@ enum class LogLevel {
/**
* Interesting informational message.
*/
DEFAULT,
NOTICE,
/**
* Warning: something may be wrong.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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,30 +27,31 @@
#include "Mapper.hxx"
#include "Permission.hxx"
#include "Listen.hxx"
#include "client/Listener.hxx"
#include "client/Client.hxx"
#include "client/ClientList.hxx"
#include "client/Config.hxx"
#include "client/List.hxx"
#include "command/AllCommands.hxx"
#include "Partition.hxx"
#include "tag/Config.hxx"
#include "ReplayGainGlobal.hxx"
#include "Idle.hxx"
#include "IdleFlags.hxx"
#include "Log.hxx"
#include "LogInit.hxx"
#include "input/Init.hxx"
#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 "AudioParser.hxx"
#include "pcm/PcmConvert.hxx"
#include "pcm/AudioParser.hxx"
#include "pcm/Convert.hxx"
#include "unix/SignalHandlers.hxx"
#include "thread/Slack.hxx"
#include "net/Init.hxx"
#include "lib/icu/Init.hxx"
#include "config/File.hxx"
#include "config/Check.hxx"
#include "config/Data.hxx"
#include "config/Param.hxx"
@@ -58,6 +59,7 @@
#include "config/Defaults.hxx"
#include "config/Option.hxx"
#include "config/Domain.hxx"
#include "config/Parser.hxx"
#include "util/RuntimeError.hxx"
#include "util/ScopeExit.hxx"
@@ -82,7 +84,7 @@
#endif
#ifdef ENABLE_SQLITE
#include "sticker/StickerDatabase.hxx"
#include "sticker/Database.hxx"
#endif
#ifdef ENABLE_ARCHIVE
@@ -95,6 +97,7 @@
#include "android/Environment.hxx"
#include "android/Context.hxx"
#include "android/LogListener.hxx"
#include "config/File.hxx"
#include "fs/FileSystem.hxx"
#include "org_musicpd_Bridge.h"
#endif
@@ -107,14 +110,12 @@
#include <systemd/sd-daemon.h>
#endif
#include <stdlib.h>
#include <climits>
#ifdef HAVE_LOCALE_H
#include <locale.h>
#ifndef ANDROID
#include <clocale>
#endif
#include <limits.h>
static constexpr size_t KILOBYTE = 1024;
static constexpr size_t MEGABYTE = 1024 * KILOBYTE;
@@ -129,17 +130,14 @@ Context *context;
LogListener *logListener;
#endif
Instance *instance;
Instance *global_instance;
struct Config {
ReplayGainConfig replay_gain;
};
static Config
LoadConfig(const ConfigData &config)
{
return {LoadReplayGainConfig(config)};
}
explicit Config(const ConfigData &raw)
:replay_gain(LoadReplayGainConfig(raw)) {}
};
#ifdef ENABLE_DAEMON
@@ -160,20 +158,31 @@ 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
static void
InitStorage(const ConfigData &config, EventLoop &event_loop)
InitStorage(Instance &instance, EventLoop &event_loop,
const ConfigData &config)
{
auto storage = CreateConfiguredStorage(config, event_loop);
if (storage == nullptr)
return;
CompositeStorage *composite = new CompositeStorage();
instance->storage = composite;
auto *composite = new CompositeStorage();
instance.storage = composite;
composite->Mount("", std::move(storage));
}
@@ -183,28 +192,29 @@ InitStorage(const ConfigData &config, EventLoop &event_loop)
* process has been daemonized.
*/
static bool
glue_db_init_and_load(const ConfigData &config)
glue_db_init_and_load(Instance &instance, const ConfigData &config)
{
auto db = CreateConfiguredDatabase(config, instance->event_loop,
instance->io_thread.GetEventLoop(),
*instance);
auto db = CreateConfiguredDatabase(config, instance.event_loop,
instance.io_thread.GetEventLoop(),
instance);
if (!db)
return true;
if (db->GetPlugin().RequireStorage()) {
InitStorage(config, instance->io_thread.GetEventLoop());
InitStorage(instance, instance.io_thread.GetEventLoop(),
config);
if (instance->storage == nullptr) {
LogDefault(config_domain,
"Found database setting without "
"music_directory - disabling database");
if (instance.storage == nullptr) {
LogNotice(config_domain,
"Found database setting without "
"music_directory - disabling database");
return true;
}
} else {
if (IsStorageConfigured(config))
LogDefault(config_domain,
"Ignoring the storage configuration "
"because the database does not need it");
LogNotice(config_domain,
"Ignoring the storage configuration "
"because the database does not need it");
}
try {
@@ -213,65 +223,66 @@ glue_db_init_and_load(const ConfigData &config)
std::throw_with_nested(std::runtime_error("Failed to open database plugin"));
}
instance->database = std::move(db);
instance.database = std::move(db);
auto *sdb = dynamic_cast<SimpleDatabase *>(instance->database.get());
auto *sdb = dynamic_cast<SimpleDatabase *>(instance.database.get());
if (sdb == nullptr)
return true;
instance->update = new UpdateService(config,
instance->event_loop, *sdb,
static_cast<CompositeStorage &>(*instance->storage),
*instance);
instance.update = new UpdateService(config,
instance.event_loop, *sdb,
static_cast<CompositeStorage &>(*instance.storage),
instance);
/* run database update after daemonization? */
return sdb->FileExists();
}
static bool
InitDatabaseAndStorage(const ConfigData &config)
InitDatabaseAndStorage(Instance &instance, const ConfigData &config)
{
const bool create_db = !glue_db_init_and_load(config);
const bool create_db = !glue_db_init_and_load(instance, config);
return create_db;
}
#endif
#ifdef ENABLE_SQLITE
/**
* Configure and initialize the sticker subsystem.
*/
static void
glue_sticker_init(const ConfigData &config)
static std::unique_ptr<StickerDatabase>
LoadStickerDatabase(const ConfigData &config)
{
#ifdef ENABLE_SQLITE
auto sticker_file = config.GetPath(ConfigOption::STICKER_FILE);
if (sticker_file.IsNull())
return;
return nullptr;
sticker_global_init(std::move(sticker_file));
#else
(void)config;
#endif
return std::make_unique<StickerDatabase>(std::move(sticker_file));
}
#endif
static void
glue_state_file_init(const ConfigData &raw_config)
glue_state_file_init(Instance &instance, const ConfigData &raw_config)
{
StateFileConfig config(raw_config);
if (!config.IsEnabled())
return;
instance->state_file = new StateFile(std::move(config),
instance->partitions.front(),
instance->event_loop);
instance->state_file->Read();
instance.state_file = std::make_unique< StateFile>(std::move(config),
instance.partitions.front(),
instance.event_loop);
instance.state_file->Read();
}
/**
* Initialize the decoder and player core, including the music pipe.
*/
static void
initialize_decoder_and_player(const ConfigData &config,
initialize_decoder_and_player(Instance &instance,
const ConfigData &config,
const ReplayGainConfig &replay_gain_config)
{
const ConfigParam *param;
@@ -279,20 +290,20 @@ initialize_decoder_and_player(const ConfigData &config,
size_t buffer_size;
param = config.GetParam(ConfigOption::AUDIO_BUFFER_SIZE);
if (param != nullptr) {
char *test;
long tmp = strtol(param->value.c_str(), &test, 10);
if (*test != '\0' || tmp <= 0 || tmp == LONG_MAX)
throw FormatRuntimeError("buffer size \"%s\" is not a "
"positive integer, line %i",
param->value.c_str(), param->line);
buffer_size = tmp * KILOBYTE;
buffer_size = param->With([](const char *s){
size_t result = ParseSize(s, KILOBYTE);
if (result <= 0)
throw FormatRuntimeError("buffer size \"%s\" is not a "
"positive integer", s);
if (buffer_size < MIN_BUFFER_SIZE) {
FormatWarning(config_domain, "buffer size %lu is too small, using %lu bytes instead",
(unsigned long)buffer_size,
(unsigned long)MIN_BUFFER_SIZE);
buffer_size = MIN_BUFFER_SIZE;
}
if (result < MIN_BUFFER_SIZE) {
FmtWarning(config_domain, "buffer size {} is too small, using {} bytes instead",
result, MIN_BUFFER_SIZE);
result = MIN_BUFFER_SIZE;
}
return result;
});
} else
buffer_size = DEFAULT_BUFFER_SIZE;
@@ -306,35 +317,26 @@ initialize_decoder_and_player(const ConfigData &config,
config.GetPositive(ConfigOption::MAX_PLAYLIST_LENGTH,
DEFAULT_PLAYLIST_MAX_LENGTH);
AudioFormat configured_audio_format = AudioFormat::Undefined();
param = config.GetParam(ConfigOption::AUDIO_OUTPUT_FORMAT);
if (param != nullptr) {
try {
configured_audio_format = ParseAudioFormat(param->value.c_str(),
true);
} catch (...) {
std::throw_with_nested(FormatRuntimeError("error parsing line %i",
param->line));
}
}
AudioFormat configured_audio_format = config.With(ConfigOption::AUDIO_OUTPUT_FORMAT, [](const char *s){
if (s == nullptr)
return AudioFormat::Undefined();
instance->partitions.emplace_back(*instance,
"default",
max_length,
buffered_chunks,
configured_audio_format,
replay_gain_config);
auto &partition = instance->partitions.back();
return ParseAudioFormat(s, true);
});
try {
param = config.GetParam(ConfigOption::REPLAYGAIN);
if (param != nullptr)
partition.replay_gain_mode =
FromString(param->value.c_str());
} catch (...) {
std::throw_with_nested(FormatRuntimeError("Failed to parse line %i",
param->line));
}
instance.partitions.emplace_back(instance,
"default",
max_length,
buffered_chunks,
configured_audio_format,
replay_gain_config);
auto &partition = instance.partitions.back();
partition.replay_gain_mode = config.With(ConfigOption::REPLAYGAIN, [](const char *s){
return s != nullptr
? FromString(s)
: ReplayGainMode::OFF;
});
}
inline void
@@ -342,7 +344,7 @@ Instance::BeginShutdownUpdate() noexcept
{
#ifdef ENABLE_DATABASE
#ifdef ENABLE_INOTIFY
mpd_inotify_finish();
inotify_update.reset();
#endif
if (update != nullptr)
@@ -354,56 +356,21 @@ inline void
Instance::BeginShutdownPartitions() noexcept
{
for (auto &partition : partitions) {
partition.pc.Kill();
partition.listener.reset();
partition.BeginShutdown();
}
}
void
Instance::OnIdle(unsigned flags)
static inline void
MainConfigured(const struct options &options, const ConfigData &raw_config)
{
/* send "idle" notifications to all subscribed
clients */
client_list->IdleAdd(flags);
if (flags & (IDLE_PLAYLIST|IDLE_PLAYER|IDLE_MIXER|IDLE_OUTPUT) &&
state_file != nullptr)
state_file->CheckModified();
}
#ifndef ANDROID
int
main(int argc, char *argv[]) noexcept
{
#ifdef _WIN32
return win32_main(argc, argv);
#else
return mpd_main(argc, argv);
#endif
}
#endif
static int
mpd_main_after_fork(const ConfigData &raw_config,
const Config &config);
static inline int
MainOrThrow(int argc, char *argv[])
{
struct options options;
#ifdef ENABLE_DAEMON
daemonize_close_stdin();
#endif
#ifndef ANDROID
#ifdef HAVE_LOCALE_H
/* initialize locale */
setlocale(LC_CTYPE,"");
setlocale(LC_COLLATE, "");
#endif
std::setlocale(LC_CTYPE,"");
std::setlocale(LC_COLLATE, "");
#endif
const ScopeIcuInit icu_init;
@@ -413,25 +380,8 @@ MainOrThrow(int argc, char *argv[])
const ODBus::ScopeInit dbus_init;
#endif
ConfigData raw_config;
#ifdef ANDROID
(void)argc;
(void)argv;
const auto sdcard = Environment::getExternalStorageDirectory();
if (!sdcard.IsNull()) {
const auto config_path =
sdcard / Path::FromFS("mpd.conf");
if (FileExists(config_path))
ReadConfigFile(raw_config, config_path);
}
#else
ParseCommandLine(argc, argv, options, raw_config);
#endif
InitPathParser(raw_config);
const auto config = LoadConfig(raw_config);
const Config config(raw_config);
#ifdef ENABLE_DAEMON
glue_daemonize_init(&options, raw_config);
@@ -441,31 +391,33 @@ MainOrThrow(int argc, char *argv[])
log_init(raw_config, options.verbose, options.log_stderr);
instance = new Instance();
AtScopeExit() {
delete instance;
instance = nullptr;
};
Instance instance;
global_instance = &instance;
#ifdef ENABLE_NEIGHBOR_PLUGINS
instance->neighbors = new NeighborGlue();
instance->neighbors->Init(raw_config,
instance->io_thread.GetEventLoop(),
*instance);
instance.neighbors = std::make_unique<NeighborGlue>();
instance.neighbors->Init(raw_config,
instance.io_thread.GetEventLoop(),
instance);
if (instance->neighbors->IsEmpty()) {
delete instance->neighbors;
instance->neighbors = nullptr;
}
if (instance.neighbors->IsEmpty())
instance.neighbors.reset();
#endif
const unsigned max_clients =
raw_config.GetPositive(ConfigOption::MAX_CONN, 10);
instance->client_list = new ClientList(max_clients);
raw_config.GetPositive(ConfigOption::MAX_CONN, 100);
instance.client_list = std::make_unique<ClientList>(max_clients);
initialize_decoder_and_player(raw_config, config.replay_gain);
const auto *input_cache_config = raw_config.GetBlock(ConfigBlockOption::INPUT_CACHE);
if (input_cache_config != nullptr) {
const InputCacheConfig c(*input_cache_config);
instance.input_cache = std::make_unique<InputCacheManager>(c);
}
listen_global_init(raw_config, *instance->partitions.front().listener);
initialize_decoder_and_player(instance,
raw_config, config.replay_gain);
listen_global_init(raw_config, *instance.partitions.front().listener);
#ifdef ENABLE_DAEMON
daemonize_set_user();
@@ -473,27 +425,6 @@ MainOrThrow(int argc, char *argv[])
AtScopeExit() { daemonize_finish(); };
#endif
return mpd_main_after_fork(raw_config, config);
}
#ifdef ANDROID
static inline
#endif
int mpd_main(int argc, char *argv[]) noexcept
{
AtScopeExit() { log_deinit(); };
try {
return MainOrThrow(argc, argv);
} catch (...) {
LogError(std::current_exception());
return EXIT_FAILURE;
}
}
static int
mpd_main_after_fork(const ConfigData &raw_config, const Config &config)
{
ConfigureFS(raw_config);
AtScopeExit() { DeinitFS(); };
@@ -510,24 +441,27 @@ mpd_main_after_fork(const ConfigData &raw_config, const Config &config)
const ScopeDecoderPluginsInit decoder_plugins_init(raw_config);
#ifdef ENABLE_DATABASE
const bool create_db = InitDatabaseAndStorage(raw_config);
const bool create_db = InitDatabaseAndStorage(instance, raw_config);
#endif
glue_sticker_init(raw_config);
#ifdef ENABLE_SQLITE
instance.sticker_database = LoadStickerDatabase(raw_config);
#endif
command_init();
for (auto &partition : instance->partitions) {
partition.outputs.Configure(instance->rtio_thread.GetEventLoop(),
for (auto &partition : instance.partitions) {
partition.outputs.Configure(instance.io_thread.GetEventLoop(),
instance.rtio_thread.GetEventLoop(),
raw_config,
config.replay_gain,
partition.pc);
config.replay_gain);
partition.UpdateEffectiveReplayGainMode();
}
client_manager_init(raw_config);
const ScopeInputPluginsInit input_plugins_init(raw_config,
instance->io_thread.GetEventLoop());
instance.io_thread.GetEventLoop());
const ScopePlaylistPluginsInit playlist_plugins_init(raw_config);
#ifdef ENABLE_DAEMON
@@ -537,42 +471,73 @@ mpd_main_after_fork(const ConfigData &raw_config, const Config &config)
#ifndef ANDROID
setup_log_output();
const ScopeSignalHandlersInit signal_handlers_init(instance->event_loop);
const ScopeSignalHandlersInit signal_handlers_init(instance);
#endif
instance->io_thread.Start();
instance->rtio_thread.Start();
instance.io_thread.Start();
instance.rtio_thread.Start();
#ifdef ENABLE_NEIGHBOR_PLUGINS
if (instance->neighbors != nullptr)
instance->neighbors->Open();
if (instance.neighbors != nullptr)
instance.neighbors->Open();
AtScopeExit(&instance) {
if (instance.neighbors != nullptr)
instance.neighbors->Close();
};
#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) {
/* the database failed to load: recreate the
database */
instance->update->Enqueue("", true);
instance.update->Enqueue("", true);
}
#endif
glue_state_file_init(raw_config);
glue_state_file_init(instance, raw_config);
#ifdef ENABLE_DATABASE
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));
if (instance.storage != nullptr &&
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
@@ -581,7 +546,7 @@ mpd_main_after_fork(const ConfigData &raw_config, const Config &config)
/* enable all audio outputs (if not already done by
playlist_state_restore() */
for (auto &partition : instance->partitions)
for (auto &partition : instance.partitions)
partition.pc.LockUpdateAudio();
#ifdef _WIN32
@@ -590,14 +555,14 @@ mpd_main_after_fork(const ConfigData &raw_config, const Config &config)
/* the MPD frontend does not care about timer slack; set it to
a huge value to allow the kernel to reduce CPU wakeups */
SetThreadTimerSlackMS(100);
SetThreadTimerSlack(std::chrono::milliseconds(100));
#ifdef ENABLE_SYSTEMD_DAEMON
sd_notify(0, "READY=1");
#endif
/* run the main loop */
instance->event_loop.Run();
instance.event_loop.Run();
#ifdef _WIN32
win32_app_stopping();
@@ -605,60 +570,106 @@ mpd_main_after_fork(const ConfigData &raw_config, const Config &config)
/* cleanup */
instance->BeginShutdownUpdate();
if (instance.state_file)
instance.state_file->Write();
if (instance->state_file != nullptr) {
instance->state_file->Write();
delete instance->state_file;
}
ZeroconfDeinit();
instance->BeginShutdownPartitions();
delete instance->client_list;
#ifdef ENABLE_NEIGHBOR_PLUGINS
if (instance->neighbors != nullptr) {
instance->neighbors->Close();
delete instance->neighbors;
}
#endif
#ifdef ENABLE_SQLITE
sticker_global_finish();
#endif
return EXIT_SUCCESS;
instance.BeginShutdownUpdate();
instance.BeginShutdownPartitions();
}
#ifdef ANDROID
static void
AndroidMain()
{
struct options options;
ConfigData raw_config;
const auto sdcard = Environment::getExternalStorageDirectory();
if (!sdcard.IsNull()) {
const auto config_path =
sdcard / Path::FromFS("mpd.conf");
if (FileExists(config_path))
ReadConfigFile(raw_config, config_path);
}
MainConfigured(options, raw_config);
}
gcc_visibility_default
JNIEXPORT void JNICALL
Java_org_musicpd_Bridge_run(JNIEnv *env, jclass, jobject _context, jobject _logListener)
{
Java::Init(env);
Java::Object::Initialise(env);
Java::File::Initialise(env);
Environment::Initialise(env);
AtScopeExit(env) { Environment::Deinitialise(env); };
context = new Context(env, _context);
AtScopeExit() { delete context; };
if (_logListener != nullptr)
logListener = new LogListener(env, _logListener);
AtScopeExit() { delete logListener; };
mpd_main(0, nullptr);
delete logListener;
delete context;
Environment::Deinitialise(env);
try {
AndroidMain();
} catch (...) {
LogError(std::current_exception());
}
}
gcc_visibility_default
JNIEXPORT void JNICALL
Java_org_musicpd_Bridge_shutdown(JNIEnv *, jclass)
{
if (instance != nullptr)
instance->Break();
if (global_instance != nullptr)
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
MainOrThrow(int argc, char *argv[])
{
struct options options;
ConfigData raw_config;
ParseCommandLine(argc, argv, options, raw_config);
MainConfigured(options, raw_config);
}
int
mpd_main(int argc, char *argv[])
{
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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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,18 +20,16 @@
#ifndef MPD_MAIN_HXX
#define MPD_MAIN_HXX
class EventLoop;
class Context;
struct Instance;
#ifdef ANDROID
#include "android/LogListener.hxx"
extern Context *context;
extern class Context *context;
extern LogListener *logListener;
#endif
extern Instance *instance;
extern Instance *global_instance;
#ifndef ANDROID
@@ -42,7 +40,7 @@ extern Instance *instance;
* after doing some initialization.
*/
int
mpd_main(int argc, char *argv[]) noexcept;
mpd_main(int argc, char *argv[]);
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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,7 +33,7 @@
#include "Main.hxx"
#endif
#include <assert.h>
#include <cassert>
/**
* The absolute path of the playlist directory encoded in the
@@ -66,10 +66,10 @@ map_uri_fs(const char *uri) noexcept
assert(uri != nullptr);
assert(*uri != '/');
if (instance->storage == nullptr)
if (global_instance->storage == nullptr)
return nullptr;
const auto music_dir_fs = instance->storage->MapFS("");
const auto music_dir_fs = global_instance->storage->MapFS("");
if (music_dir_fs.IsNull())
return nullptr;
@@ -84,10 +84,10 @@ std::string
map_fs_to_utf8(Path path_fs) noexcept
{
if (path_fs.IsAbsolute()) {
if (instance->storage == nullptr)
if (global_instance->storage == nullptr)
return std::string();
const auto music_dir_fs = instance->storage->MapFS("");
const auto music_dir_fs = global_instance->storage->MapFS("");
if (music_dir_fs.IsNull())
return std::string();
@@ -119,7 +119,7 @@ map_spl_utf8_to_fs(const char *name) noexcept
filename_utf8.append(PLAYLIST_FILE_SUFFIX);
const auto filename_fs =
AllocatedPath::FromUTF8(filename_utf8.c_str());
AllocatedPath::FromUTF8(filename_utf8);
if (filename_fs.IsNull())
return nullptr;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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,7 +20,7 @@
#include "MusicBuffer.hxx"
#include "MusicChunk.hxx"
#include <assert.h>
#include <cassert>
MusicBuffer::MusicBuffer(unsigned num_chunks)
:buffer(num_chunks) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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
@@ -18,10 +18,10 @@
*/
#include "MusicChunk.hxx"
#include "AudioFormat.hxx"
#include "pcm/AudioFormat.hxx"
#include "tag/Tag.hxx"
#include <assert.h>
#include <cassert>
MusicChunkInfo::MusicChunkInfo() noexcept = default;
MusicChunkInfo::~MusicChunkInfo() noexcept = default;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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
@@ -26,14 +26,13 @@
#include "util/WritableBuffer.hxx"
#ifndef NDEBUG
#include "AudioFormat.hxx"
#include "pcm/AudioFormat.hxx"
#endif
#include <cstddef>
#include <cstdint>
#include <memory>
#include <stdint.h>
#include <stddef.h>
static constexpr size_t CHUNK_SIZE = 4096;
struct AudioFormat;
@@ -43,15 +42,7 @@ struct MusicChunk;
/**
* Meta information for #MusicChunk.
*/
struct alignas(8) MusicChunkInfo {
/* align to multiple of 8 bytes, which adds padding at the
end, so the size of MusicChunk::data is also a multiple of
8 bytes; this is a workaround for a bug in the DSD_U32 and
DoP converters which require processing 8 bytes at a time,
discarding the remainder */
/* TODO: once all converters have been fixed, we should remove
this workaround */
struct MusicChunkInfo {
/** the next chunk in a linked list */
MusicChunkPtr next;
@@ -114,7 +105,7 @@ struct alignas(8) 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
};
@@ -127,10 +118,6 @@ struct MusicChunk : MusicChunkInfo {
/** the data (probably PCM) */
uint8_t data[CHUNK_SIZE - sizeof(MusicChunkInfo)];
/* TODO: remove this check once all converters have been fixed
(see comment in struct MusicChunkInfo for details) */
static_assert(sizeof(data) % 8 == 0, "Wrong alignment");
/**
* Prepares appending to the music chunk. Returns a buffer
* where you may write into. After you are finished, call

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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,6 +20,8 @@
#include "MusicPipe.hxx"
#include "MusicChunk.hxx"
#include <cassert>
#ifndef NDEBUG
bool

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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,14 +22,11 @@
#include "MusicChunkPtr.hxx"
#include "thread/Mutex.hxx"
#include "util/Compiler.h"
#ifndef NDEBUG
#include "AudioFormat.hxx"
#include "pcm/AudioFormat.hxx"
#endif
#include <assert.h>
/**
* A queue of #MusicChunk objects. One party appends chunks at the
* tail, and the other consumes them from the head.
@@ -61,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;
@@ -70,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
@@ -78,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();
@@ -102,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;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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,24 +20,34 @@
#include "config.h"
#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"
#include "client/Listener.hxx"
#include "client/Client.hxx"
#include "input/cache/Manager.hxx"
#include "util/Domain.hxx"
static constexpr Domain cache_domain("cache");
Partition::Partition(Instance &_instance,
const char *_name,
unsigned max_length,
unsigned buffer_chunks,
AudioFormat configured_audio_format,
const ReplayGainConfig &replay_gain_config)
const ReplayGainConfig &replay_gain_config) noexcept
:instance(_instance),
name(_name),
listener(new ClientListener(instance.event_loop, *this)),
idle_monitor(instance.event_loop, BIND_THIS_METHOD(OnIdleMonitor)),
global_events(instance.event_loop, BIND_THIS_METHOD(OnGlobalEvent)),
playlist(max_length, *this),
outputs(*this),
pc(*this, outputs, buffer_chunks,
outputs(pc, *this),
pc(*this, outputs,
instance.input_cache.get(),
buffer_chunks,
configured_audio_format, replay_gain_config)
{
UpdateEffectiveReplayGainMode();
@@ -46,13 +56,52 @@ Partition::Partition(Instance &_instance,
Partition::~Partition() noexcept = default;
void
Partition::EmitIdle(unsigned mask)
Partition::BeginShutdown() noexcept
{
instance.EmitIdle(mask);
pc.Kill();
listener.reset();
}
static void
PrefetchSong(InputCacheManager &cache, const char *uri) noexcept
{
if (cache.Contains(uri))
return;
FmtDebug(cache_domain, "Prefetch '{}'", uri);
try {
cache.Prefetch(uri);
} catch (...) {
FmtError(cache_domain,
"Prefetch '{}' failed: {}",
uri, std::current_exception());
}
}
static void
PrefetchSong(InputCacheManager &cache, const DetachedSong &song) noexcept
{
PrefetchSong(cache, song.GetURI());
}
inline void
Partition::PrefetchQueue() noexcept
{
if (!instance.input_cache)
return;
auto &cache = *instance.input_cache;
int next = playlist.GetNextPosition();
if (next >= 0)
PrefetchSong(cache, playlist.queue.Get(next));
// TODO: prefetch more songs
}
void
Partition::UpdateEffectiveReplayGainMode()
Partition::UpdateEffectiveReplayGainMode() noexcept
{
auto mode = replay_gain_mode;
if (mode == ReplayGainMode::AUTO)
@@ -68,7 +117,7 @@ Partition::UpdateEffectiveReplayGainMode()
#ifdef ENABLE_DATABASE
const Database *
Partition::GetDatabase() const
Partition::GetDatabase() const noexcept
{
return instance.GetDatabase();
}
@@ -80,7 +129,7 @@ Partition::GetDatabaseOrThrow() const
}
void
Partition::DatabaseModified(const Database &db)
Partition::DatabaseModified(const Database &db) noexcept
{
playlist.DatabaseModified(db);
EmitIdle(IDLE_DATABASE);
@@ -89,7 +138,7 @@ Partition::DatabaseModified(const Database &db)
#endif
void
Partition::TagModified()
Partition::TagModified() noexcept
{
auto song = pc.LockReadTaggedSong();
if (song)
@@ -103,31 +152,35 @@ Partition::TagModified(const char *uri, const Tag &tag) noexcept
}
void
Partition::SyncWithPlayer()
Partition::SyncWithPlayer() noexcept
{
playlist.SyncWithPlayer(pc);
/* TODO: invoke this function in batches, to let the hard disk
spin down in between */
PrefetchQueue();
}
void
Partition::BorderPause()
Partition::BorderPause() noexcept
{
playlist.BorderPause(pc);
}
void
Partition::OnQueueModified()
Partition::OnQueueModified() noexcept
{
EmitIdle(IDLE_PLAYLIST);
}
void
Partition::OnQueueOptionsChanged()
Partition::OnQueueOptionsChanged() noexcept
{
EmitIdle(IDLE_OPTIONS);
}
void
Partition::OnQueueSongStarted()
Partition::OnQueueSongStarted() noexcept
{
EmitIdle(IDLE_PLAYER);
}
@@ -151,7 +204,7 @@ Partition::OnBorderPause() noexcept
}
void
Partition::OnMixerVolumeChanged(gcc_unused Mixer &mixer, gcc_unused int volume)
Partition::OnMixerVolumeChanged(Mixer &, int) noexcept
{
InvalidateHardwareVolume();
@@ -160,7 +213,19 @@ Partition::OnMixerVolumeChanged(gcc_unused Mixer &mixer, gcc_unused int volume)
}
void
Partition::OnGlobalEvent(unsigned mask)
Partition::OnIdleMonitor(unsigned mask) noexcept
{
/* send "idle" notifications to all subscribed
clients */
for (auto &client : clients)
client.IdleAdd(mask);
if (mask & (IDLE_PLAYLIST|IDLE_PLAYER|IDLE_MIXER|IDLE_OUTPUT))
instance.OnStateModified();
}
void
Partition::OnGlobalEvent(unsigned mask) noexcept
{
if ((mask & SYNC_WITH_PLAYER) != 0)
SyncWithPlayer();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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,19 +27,23 @@
#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"
#include "util/Compiler.h"
#include "config.h"
#include <boost/intrusive/list.hpp>
#include <string>
#include <memory>
struct Instance;
struct RangeArg;
class MultipleOutputs;
class SongLoader;
class ClientListener;
class Client;
/**
* A partition of the Music Player Daemon. It is a separate unit with
@@ -56,6 +60,16 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
std::unique_ptr<ClientListener> listener;
boost::intrusive::list<Client,
boost::intrusive::base_hook<boost::intrusive::list_base_hook<boost::intrusive::tag<Partition>,
boost::intrusive::link_mode<boost::intrusive::normal_link>>>,
boost::intrusive::constant_time_size<false>> clients;
/**
* Monitor for idle events local to this partition.
*/
MaskMonitor idle_monitor;
MaskMonitor global_events;
struct playlist playlist;
@@ -71,17 +85,34 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
unsigned max_length,
unsigned buffer_chunks,
AudioFormat configured_audio_format,
const ReplayGainConfig &replay_gain_config);
const ReplayGainConfig &replay_gain_config) noexcept;
~Partition() noexcept;
void EmitGlobalEvent(unsigned mask) {
void BeginShutdown() noexcept;
void EmitGlobalEvent(unsigned mask) noexcept {
global_events.OrMask(mask);
}
void EmitIdle(unsigned mask);
/**
* Emit an "idle" event to all clients of this partition.
*
* This method can be called from any thread.
*/
void EmitIdle(unsigned mask) noexcept {
idle_monitor.OrMask(mask);
}
void ClearQueue() {
/**
* Populate the #InputCacheManager with soon-to-be-played song
* files.
*
* Errors will be logged.
*/
void PrefetchQueue() noexcept;
void ClearQueue() noexcept {
playlist.Clear(pc);
}
@@ -104,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) {
void StaleSong(const char *uri) noexcept {
playlist.StaleSong(pc, uri);
}
void Shuffle(unsigned start, unsigned end) {
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) {
@@ -132,17 +159,15 @@ 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) {
playlist.SetPriorityId(pc, song_id, priority);
}
void Stop() {
void Stop() noexcept {
playlist.Stop(pc);
}
@@ -174,27 +199,27 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
playlist.SeekCurrent(pc, seek_time, relative);
}
void SetRepeat(bool new_value) {
void SetRepeat(bool new_value) noexcept {
playlist.SetRepeat(pc, new_value);
}
bool GetRandom() const {
bool GetRandom() const noexcept {
return playlist.GetRandom();
}
void SetRandom(bool new_value) {
void SetRandom(bool new_value) noexcept {
playlist.SetRandom(pc, new_value);
}
void SetSingle(SingleMode new_value) {
void SetSingle(SingleMode new_value) noexcept {
playlist.SetSingle(pc, new_value);
}
void SetConsume(bool new_value) {
void SetConsume(bool new_value) noexcept {
playlist.SetConsume(new_value);
}
void SetReplayGainMode(ReplayGainMode mode) {
void SetReplayGainMode(ReplayGainMode mode) noexcept {
replay_gain_mode = mode;
UpdateEffectiveReplayGainMode();
}
@@ -203,7 +228,7 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
* Publishes the effective #ReplayGainMode to all subsystems.
* #ReplayGainMode::AUTO is substituted.
*/
void UpdateEffectiveReplayGainMode();
void UpdateEffectiveReplayGainMode() noexcept;
#ifdef ENABLE_DATABASE
/**
@@ -211,7 +236,7 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
* if this MPD configuration has no database (no
* music_directory was configured).
*/
const Database *GetDatabase() const;
const Database *GetDatabase() const noexcept;
const Database &GetDatabaseOrThrow() const;
@@ -219,14 +244,14 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
* The database has been modified. Propagate the change to
* all subsystems.
*/
void DatabaseModified(const Database &db);
void DatabaseModified(const Database &db) noexcept;
#endif
/**
* A tag in the play queue has been modified by the player
* thread. Propagate the change to all subsystems.
*/
void TagModified();
void TagModified() noexcept;
/**
* The tag of the given song has been modified. Propagate the
@@ -237,19 +262,19 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
/**
* Synchronize the player with the play queue.
*/
void SyncWithPlayer();
void SyncWithPlayer() noexcept;
/**
* Border pause has just been enabled. Change single mode to off
* if it was one-shot.
*/
void BorderPause();
void BorderPause() noexcept;
private:
/* virtual methods from class QueueListener */
void OnQueueModified() override;
void OnQueueOptionsChanged() override;
void OnQueueSongStarted() override;
void OnQueueModified() noexcept override;
void OnQueueOptionsChanged() noexcept override;
void OnQueueSongStarted() noexcept override;
/* virtual methods from class PlayerListener */
void OnPlayerSync() noexcept override;
@@ -257,10 +282,13 @@ private:
void OnBorderPause() noexcept override;
/* virtual methods from class MixerListener */
void OnMixerVolumeChanged(Mixer &mixer, int volume) override;
void OnMixerVolumeChanged(Mixer &mixer, int volume) noexcept override;
/* callback for #idle_monitor */
void OnIdleMonitor(unsigned mask) noexcept;
/* callback for #global_events */
void OnGlobalEvent(unsigned mask);
void OnGlobalEvent(unsigned mask) noexcept;
};
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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,14 +22,18 @@
#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"
#include <algorithm>
#include <cassert>
#include <cstring>
#include <map>
#include <string>
#include <assert.h>
#include <string.h>
#include <utility>
static constexpr char PERMISSION_PASSWORD_CHAR = '@';
static constexpr char PERMISSION_SEPARATOR = ',';
@@ -40,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 },
@@ -53,36 +58,34 @@ static unsigned permission_default;
static unsigned local_permissions;
#endif
#ifdef HAVE_TCP
static std::map<std::string, unsigned> host_passwords;
#endif
static unsigned
ParsePermission(const char *p)
ParsePermission(StringView s)
{
for (auto i = permission_names; i->name != nullptr; ++i)
if (strcmp(p, i->name) == 0)
if (s.Equals(i->name))
return i->value;
throw FormatRuntimeError("unknown permission \"%s\"", p);
throw FormatRuntimeError("unknown permission \"%.*s\"",
int(s.size), s.data);
}
static unsigned parsePermissions(const char *string)
static unsigned
parsePermissions(std::string_view string)
{
assert(string != nullptr);
const char *const end = string + strlen(string);
unsigned permission = 0;
while (true) {
const char *comma = std::find(string, end,
PERMISSION_SEPARATOR);
if (comma > string) {
const std::string name(string, comma);
permission |= ParsePermission(name.c_str());
}
if (comma == end)
break;
for (const auto i : IterableSplitString(string, PERMISSION_SEPARATOR))
if (!i.empty())
permission |= ParsePermission(i);
string = comma + 1;
}
/* for backwards compatiblity with MPD 0.22 and older,
"control" implies "play" */
if (permission & PERMISSION_CONTROL)
permission |= PERMISSION_PLAYER;
return permission;
}
@@ -90,58 +93,86 @@ static unsigned parsePermissions(const char *string)
void
initPermissions(const ConfigData &config)
{
unsigned permission;
permission_default = PERMISSION_READ | PERMISSION_ADD |
PERMISSION_PLAYER |
PERMISSION_CONTROL | PERMISSION_ADMIN;
for (const auto &param : config.GetParamList(ConfigOption::PASSWORD)) {
permission_default = 0;
const char *separator = strchr(param.value.c_str(),
PERMISSION_PASSWORD_CHAR);
param.With([](const char *value){
const char *separator = std::strchr(value,
PERMISSION_PASSWORD_CHAR);
if (separator == NULL)
throw FormatRuntimeError("\"%c\" not found in password string "
"\"%s\", line %i",
PERMISSION_PASSWORD_CHAR,
param.value.c_str(),
param.line);
if (separator == nullptr)
throw FormatRuntimeError("\"%c\" not found in password string",
PERMISSION_PASSWORD_CHAR);
std::string password(param.value.c_str(), separator);
std::string password(value, separator);
permission = parsePermissions(separator + 1);
permission_passwords.insert(std::make_pair(std::move(password),
permission));
unsigned permission = parsePermissions(separator + 1);
permission_passwords.emplace(std::move(password), permission);
});
}
const ConfigParam *param;
param = config.GetParam(ConfigOption::DEFAULT_PERMS);
if (param)
permission_default = parsePermissions(param->value.c_str());
config.With(ConfigOption::DEFAULT_PERMS, [](const char *value){
if (value != nullptr)
permission_default = parsePermissions(value);
});
#ifdef HAVE_UN
param = config.GetParam(ConfigOption::LOCAL_PERMISSIONS);
if (param != nullptr)
local_permissions = parsePermissions(param->value.c_str());
else
local_permissions = permission_default;
local_permissions = config.With(ConfigOption::LOCAL_PERMISSIONS, [](const char *value){
return value != nullptr
? parsePermissions(value)
: 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
}
int getPermissionFromPassword(char const* password, unsigned* permission)
#ifdef HAVE_TCP
int
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 getDefaultPermissions(void)
unsigned
getDefaultPermissions() noexcept
{
return permission_default;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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,24 +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(char const* password, unsigned* permission);
/**
* @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();
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);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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,11 +21,12 @@
#include "db/PlaylistVector.hxx"
#include "fs/io/TextFile.hxx"
#include "fs/io/BufferedOutputStream.hxx"
#include "time/ChronoUtil.hxx"
#include "util/StringStrip.hxx"
#include "util/ChronoUtil.hxx"
#include "util/RuntimeError.hxx"
#include <string.h>
#include <cstring>
#include <stdlib.h>
void
@@ -49,8 +50,8 @@ playlist_metadata_load(TextFile &file, PlaylistVector &pv, const char *name)
const char *value;
while ((line = file.ReadLine()) != nullptr &&
strcmp(line, "playlist_end") != 0) {
colon = strchr(line, ':');
std::strcmp(line, "playlist_end") != 0) {
colon = std::strchr(line, ':');
if (colon == nullptr || colon == line)
throw FormatRuntimeError("unknown line in db: %s",
line);
@@ -58,7 +59,7 @@ playlist_metadata_load(TextFile &file, PlaylistVector &pv, const char *name)
*colon++ = 0;
value = StripLeft(colon);
if (strcmp(line, "mtime") == 0)
if (std::strcmp(line, "mtime") == 0)
pm.mtime = std::chrono::system_clock::from_time_t(strtol(value, nullptr, 10));
else
throw FormatRuntimeError("unknown line in db: %s",

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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
@@ -39,15 +39,11 @@
#include "fs/FileSystem.hxx"
#include "fs/FileInfo.hxx"
#include "fs/DirectoryReader.hxx"
#include "util/Macros.hxx"
#include "util/StringCompare.hxx"
#include "util/UriUtil.hxx"
#include "util/UriExtract.hxx"
#include <memory>
#include <assert.h>
#include <string.h>
#include <errno.h>
#include <cassert>
#include <cstring>
static const char PLAYLIST_COMMENT = '#';
@@ -84,9 +80,9 @@ spl_valid_name(const char *name_utf8)
* filenames isn't going to happen, either.
*/
return strchr(name_utf8, '/') == nullptr &&
strchr(name_utf8, '\n') == nullptr &&
strchr(name_utf8, '\r') == nullptr;
return std::strchr(name_utf8, '/') == nullptr &&
std::strchr(name_utf8, '\n') == nullptr &&
std::strchr(name_utf8, '\r') == nullptr;
}
static const AllocatedPath &

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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,11 +22,7 @@
#include "PlaylistError.hxx"
#include "queue/Playlist.hxx"
#include "queue/QueuePrint.hxx"
#include "SongPrint.hxx"
#include "Partition.hxx"
#include "Instance.hxx"
#include "db/Interface.hxx"
#include "client/Response.hxx"
#include "protocol/RangeArg.hxx"
#define SONG_FILE "file: "
#define SONG_TIME "Time: "
@@ -40,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
@@ -67,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
@@ -92,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);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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,9 +20,10 @@
#ifndef MPD_PLAYLIST_PRINT_HXX
#define MPD_PLAYLIST_PRINT_HXX
#include <stdint.h>
#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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 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
@@ -30,9 +30,7 @@
#include "fs/FileSystem.hxx"
#include "fs/io/FileOutputStream.hxx"
#include "fs/io/BufferedOutputStream.hxx"
#include "util/UriUtil.hxx"
#include <exception>
#include "util/UriExtract.hxx"
static void
playlist_print_path(BufferedOutputStream &os, const Path path)

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