Compare commits

...

1329 Commits

Author SHA1 Message Date
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
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
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
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  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
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
Max Kellermann
55b8f2c533 NEWS: add line about Solaris change 2020-04-14 16:11:18 +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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
b11c5f8d30 util/{Const,Writable}Buffer: drop more "_type" suffixes from type names 2020-01-12 14:39:54 +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
803a48e96d Merge tag 'v0.21.18'
release v0.21.18
2019-12-24 16:31:06 +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
Jacob Vosmaer
83acbe1002 input/cache: use simpler intrusive::set API 2019-12-18 23:15:46 +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
b449627265 fs/io/Reader: relicense to BSD-2 2019-12-16 17:13:55 +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
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
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
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
e1867a99e9 Merge tag 'v0.21.16'
release v0.21.16
2019-10-16 12:03:12 +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
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
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
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
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
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
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
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
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
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
1520 changed files with 25384 additions and 13619 deletions
.clang-format
.github
.gitignore.travis.ymlAUTHORSNEWS
android
doc
meson.buildmeson_options.txt
python/build
src
BulkEdit.hxxChrono.hxxCommandLine.cxxCommandLine.hxxGitVersion.cxxGitVersion.hxxIcyMetaDataParser.cxxIcyMetaDataParser.hxxIdle.cxxIdle.hxxIdleFlags.cxxIdleFlags.hxxInstance.cxxInstance.hxxListen.cxxListen.hxxLocateUri.cxxLocateUri.hxxLog.cxxLog.hxxLogBackend.cxxLogBackend.hxxLogInit.cxxLogInit.hxxLogLevel.hxxLogV.hxxMain.cxxMain.hxxMapper.cxxMapper.hxxMixRampInfo.hxxMusicBuffer.cxxMusicBuffer.hxxMusicChunk.cxxMusicChunk.hxxMusicChunkPtr.cxxMusicChunkPtr.hxxMusicPipe.cxxMusicPipe.hxxPartition.cxxPartition.hxxPermission.cxxPermission.hxxPlaylistDatabase.cxxPlaylistDatabase.hxxPlaylistError.cxxPlaylistError.hxxPlaylistFile.cxxPlaylistFile.hxxPlaylistPrint.cxxPlaylistPrint.hxxPlaylistSave.cxxPlaylistSave.hxxPluginUnavailable.hxxRemoteTagCache.cxxRemoteTagCache.hxxRemoteTagCacheHandler.hxxReplayGainConfig.hxxReplayGainGlobal.cxxReplayGainGlobal.hxxReplayGainInfo.cxxReplayGainInfo.hxxReplayGainMode.cxxReplayGainMode.hxxSingleMode.cxxSingleMode.hxxSongLoader.cxxSongLoader.hxxSongPrint.cxxSongPrint.hxxSongSave.cxxSongSave.hxxSongUpdate.cxxStateFile.cxxStateFile.hxxStateFileConfig.cxxStateFileConfig.hxxStats.cxxStats.hxxTagAny.cxxTagAny.hxxTagArchive.cxxTagArchive.hxxTagFile.cxxTagFile.hxxTagPrint.cxxTagPrint.hxxTagSave.cxxTagSave.hxxTagStream.cxxTagStream.hxxTimePrint.cxxTimePrint.hxx
android
apple
archive
client
command
config
db
decoder
Bridge.cxxBridge.hxxClient.hxxCommand.hxxControl.cxxControl.hxxDecoderAPI.cxxDecoderAPI.hxxDecoderBuffer.cxxDecoderBuffer.hxxDecoderList.cxxDecoderList.hxxDecoderPlugin.cxxDecoderPlugin.hxxDecoderPrint.cxxDecoderPrint.hxxDomain.cxxDomain.hxxReader.cxxReader.hxxThread.cxxmeson.build
plugins
encoder
event
filter
fs
input
AsyncInputStream.cxxAsyncInputStream.hxxBufferedInputStream.cxxBufferedInputStream.hxxBufferingInputStream.cxxBufferingInputStream.hxxCondHandler.hxxError.cxxError.hxxFailingInputStream.hxxHandler.hxxIcyInputStream.cxxIcyInputStream.hxxInit.cxxInit.hxxInputPlugin.cxxInputPlugin.hxxInputStream.cxxInputStream.hxxLocalOpen.cxxLocalOpen.hxxMaybeBufferedInputStream.cxxMaybeBufferedInputStream.hxxOffset.hxxOpen.cxxProxyInputStream.cxxProxyInputStream.hxxPtr.hxxReader.cxxReader.hxxRegistry.cxxRegistry.hxxRemoteTagScanner.hxxRewindInputStream.cxxRewindInputStream.hxxScanTags.cxxScanTags.hxxTextInputStream.cxxTextInputStream.hxxThreadInputStream.cxxThreadInputStream.hxx
cache
meson.build
plugins
io
java
lib
alsa
chromaprint
crypto
curl
dbus
expat
ffmpeg
gcrypt
icu
nfs
pcre
pulse
smbclient
sqlite
systemd
upnp
xiph
yajl
ls.cxxls.hxx
mixer
neighbor
net
open.h
output
pcm
player
playlist
protocol
queue
song
sticker
storage
system
tag
thread
time
unix
util
win32
zeroconf
subprojects
systemd
test
win32

17
.clang-format Normal 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

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

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

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

9
.github/ISSUE_TEMPLATE/question.md vendored Normal 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

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

@@ -67,32 +67,6 @@ jobs:
env:
- MATRIX_EVAL="export PATH=\$HOME/.local/bin:\$PATH"
# Ubuntu Trusty (16.04) with GCC 6
- os: linux
dist: trusty
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
- 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 --no-cache-dir
install:
- /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='ccache gcc-6' CXX='ccache g++-6' LDFLAGS=-fuse-ld=gold PATH=\$HOME/.local/bin:\$PATH"
# Ubuntu Trusty (16.04) with GCC 8
- os: linux
dist: trusty
@@ -120,7 +94,7 @@ jobs:
- MATRIX_EVAL="export CC='ccache gcc-8' CXX='ccache g++-8' LDFLAGS=-fuse-ld=gold PATH=\$HOME/.local/bin:\$PATH"
- os: osx
osx_image: xcode9.4
osx_image: xcode10.3
addons:
homebrew:
packages:
@@ -135,7 +109,8 @@ jobs:
- chromaprint
- libsamplerate
- libsoxr
- libzzip
# libzzip appears to be broken on Homebrew: "ld: library not found for -lzzip"
#- libzzip
- flac
- opus
- libvorbis

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

118
NEWS

@@ -1,3 +1,121 @@
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

@@ -2,8 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.musicpd"
android:installLocation="auto"
android:versionCode="46"
android:versionName="0.21.23">
android:versionCode="51"
android:versionName="0.22.1">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28"/>

@@ -26,7 +26,7 @@ android_abis = {
'ndk_arch': 'arm',
'toolchain_arch': 'arm-linux-androideabi',
'llvm_triple': 'armv7-linux-androideabi',
'cflags': '-march=armv7-a -mfpu=vfp -mfloat-abi=softfp',
'cflags': '-fpic -march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp',
},
'arm64-v8a': {
@@ -34,7 +34,7 @@ android_abis = {
'ndk_arch': 'arm64',
'toolchain_arch': 'aarch64-linux-android',
'llvm_triple': 'aarch64-linux-android',
'cflags': '',
'cflags': '-fpic',
},
'x86': {
@@ -42,7 +42,7 @@ android_abis = {
'ndk_arch': 'x86',
'toolchain_arch': 'x86',
'llvm_triple': 'i686-linux-android',
'cflags': '-march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32',
'cflags': '-fPIC -march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32',
},
'x86_64': {
@@ -50,7 +50,7 @@ android_abis = {
'ndk_arch': 'x86_64',
'toolchain_arch': 'x86_64',
'llvm_triple': 'x86_64-linux-android',
'cflags': '-m64',
'cflags': '-fPIC -m64',
},
}
@@ -97,7 +97,6 @@ class AndroidNdkToolchain:
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')
@@ -169,6 +168,9 @@ thirdparty_libs = [
opus,
flac,
libid3tag,
libmodplug,
wildmidi,
gme,
ffmpeg,
curl,
libexpat,

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

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

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

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

@@ -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-2020 The Music Player Daemon Project'
author = 'Max Kellermann'
# The version info for the project you're documenting, acts as replacement for
@@ -38,7 +38,7 @@ author = 'Max Kellermann'
# built documents.
#
# The short X.Y version.
version = '0.21.23'
version = '0.22.1'
# The full version, including alpha/beta/rc tags.
release = version
@@ -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)
]

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

@@ -1,33 +1,51 @@
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',
'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()),
)
custom_target(
'upload',
input: sphinx_output,
output: 'upload',
build_always_stale: true,
command: [
'rsync', '-vpruz', '--delete', meson.current_build_dir() + '/',
'www.musicpd.org:/var/www/mpd/doc/',
'--chmod=Dug+rwx,Do+rx,Fug+rw,Fo+r',
'--include=html', '--include=html/**',
'--exclude=*',
],
)
endif
if get_option('manpages')
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

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

@@ -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 ``/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:`~/.mpdconf`
User configuration file.
: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/

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

202
doc/mpd.conf.5.rst Normal file

@@ -0,0 +1,202 @@
========
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`.
Lines beginning with a :samp:`#` character are comments. All other
non-empty lines specify parameters and their values. These lines
contain the parameter name and parameter value (surrounded by double
quotes) separated by whitespace (either tabs or spaces). For
example::
parameter "value"
The exception to this rule is the audio_output parameter, which is of
the form::
audio_output {
parameter1 "value"
parameter2 "value"
}
Parameters that take a file or directory as an argument should use absolute paths.
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/
REQUIRED 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.
OPTIONAL PARAMETERS
-------------------
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 <default, secure, or verbose>
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 http://www.replaygain.org/). 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:`~/.mpdconf`
User configuration file.
:file:`/etc/mpd.conf`
Global configuration file.
SEE ALSO
--------
:manpage:`mpd(1)`, :manpage:`mpc(1)`

@@ -89,12 +89,10 @@
#
#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.
#
#log_level "default"
#log_level "notice"
#
# Setting "restore_paused" to "yes" puts MPD into pause mode instead
# of starting playback after startup.
@@ -280,6 +278,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 +292,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 {

@@ -27,7 +27,7 @@ The default plugin. Stores a copy of the database in memory. A file is used for
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. This is useful when you mount the music directory via NFS/SMB, and the file server already runs a :program:`MPD` instance. Only the file server needs to update the database.
.. list-table::
:widths: 20 80
@@ -60,25 +60,25 @@ 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`.
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 +116,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 +131,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 +186,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
@@ -182,7 +209,9 @@ Note that unless overridden by the below settings (e.g. by setting them to a bla
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 +223,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
@@ -243,7 +293,9 @@ Play songs from the commercial streaming service Qobuz. It plays URLs in the for
tidal
-----
Play songs from the commercial streaming service `Tidal <http://tidal.com/>`_. It plays URLs in the form tidal://track/ID, e.g.:
Play songs from the commercial streaming service `Tidal
<http://tidal.com/>`_. It plays URLs in the form ``tidal://track/ID``,
e.g.:
.. warning::
@@ -298,6 +350,8 @@ faad
Decodes AAC files using libfaad.
.. _decoder_ffmpeg:
ffmpeg
------
@@ -367,30 +421,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
---
@@ -434,7 +480,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 +492,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 +506,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**
@@ -696,6 +746,25 @@ Valid quality values for libsoxr:
* "medium"
* "low"
* "quick"
* "custom"
If the quality is set to custom also the following settings are available:
* - 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:
@@ -840,6 +909,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.
@@ -974,6 +1047,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.
@@ -1044,7 +1119,8 @@ 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.
solaris
@@ -1061,11 +1137,58 @@ 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".
.. _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://libav.org/documentation/libavfilter.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
---------
@@ -1148,3 +1271,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/>`_.

@@ -66,7 +66,16 @@ 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. 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 +172,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 +218,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::
@@ -274,6 +283,12 @@ The following tags are supported by :program:`MPD`:
* **date**: the song's release date. This is usually a 4-digit year.
* **composer**: the artist who composed the song.
* **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>`_
* **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.
@@ -374,7 +389,9 @@ Querying :program:`MPD`'s status
: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:
@@ -398,9 +415,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 +443,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``
@@ -464,7 +485,8 @@ 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
@@ -514,7 +536,7 @@ 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.
@@ -534,10 +556,10 @@ Controlling playback
:command:`next`
Plays next song in the playlist.
:command:`pause {PAUSE}`
Toggles pause/resumes playing, ``PAUSE`` is 0 or 1.
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 [SONGPOS]`
Begins playing the playlist at song number
@@ -808,11 +830,12 @@ The music database
==================
: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,7 +844,7 @@ The music database
Example::
albumart
albumart foo/bar.ogg 0
size: 1024768
binary: 8192
<8192 bytes>
@@ -845,10 +868,21 @@ 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 {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}]`
@@ -875,7 +909,7 @@ The music database
.. _command_findadd:
:command:`findadd {FILTER}`
:command:`findadd {FILTER} [sort {TYPE}] [window {START:END}]`
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
@@ -980,6 +1014,30 @@ The music database
decoder plugins support it. For example, on Ogg files,
this lists the Vorbis comments.
: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}]`
@@ -990,14 +1048,14 @@ The music database
.. _command_searchadd:
:command:`searchadd {FILTER}`
:command:`searchadd {FILTER} [sort {TYPE}] [window {START:END}]`
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}`
: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``.
@@ -1037,8 +1095,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:
@@ -1187,6 +1245,8 @@ Connection settings
Announce that this client is interested in all tag
types. This is the default setting for new clients.
.. _partition_commands:
Partition commands
==================
@@ -1207,6 +1267,13 @@ client is assigned to one partition at a time.
:command:`newpartition {NAME}`
Create a new partition.
:command:`delpartition {NAME}`
Delete a partition. The partition must be empty (no connected
clients and no outputs).
:command:`moveoutput {OUTPUTNAME}`
Move an output to the current partition.
Audio output devices
====================
@@ -1296,6 +1363,9 @@ 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 {NAME}`
Subscribe to a channel. The channel is created if it
does not exist already. The name may consist of

@@ -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,7 +55,7 @@ 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)
* a C++17 compiler (e.g. GCC 8 or clang 5)
* `Meson 0.49.0 <http://mesonbuild.com/>`__ and `Ninja
<https://ninja-build.org/>`__
* Boost 1.58
@@ -185,47 +187,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
*************
@@ -260,6 +221,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
-------------------------------
@@ -336,6 +304,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
---------------------------
@@ -419,7 +425,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,...**"
@@ -714,8 +720,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
^^^^^^^^
@@ -763,22 +770,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.
@@ -796,10 +805,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.
@@ -814,6 +823,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
----------
@@ -953,6 +1045,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
************
@@ -977,7 +1085,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
-------
@@ -990,34 +1098,66 @@ The :program:`MPD` project runs a `forum <https://forum.musicpd.org/>`_ and an I
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.
@@ -1057,7 +1197,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

@@ -1,11 +1,18 @@
project(
'mpd',
['c', 'cpp'],
version: '0.21.23',
version: '0.22.1',
meson_version: '>= 0.49.0',
default_options: [
'c_std=c99',
'cpp_std=c++14'
'build.c_std=c99',
'cpp_std=c++17',
'build.cpp_std=c++17',
'warning_level=3',
# This is only here to build subprojects as static libraries; MPD
# itself doesn't ship any libraries.
'default_library=static',
],
license: 'GPLv2+',
)
@@ -15,18 +22,20 @@ 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('<5')
warning('Your clang version is too old. You need at least version 5.')
endif
version_conf = configuration_data()
version_conf.set_quoted('PACKAGE', meson.project_name())
version_conf.set_quoted('PACKAGE_NAME', meson.project_name())
version_conf.set_quoted('VERSION', meson.project_version())
version_conf.set_quoted('PROTOCOL_VERSION', '0.22.0')
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 = [
@@ -40,8 +49,8 @@ common_cxxflags = [
]
test_common_flags = [
'-Wall',
'-Wextra',
'-Wvla',
'-Wdouble-promotion',
'-fvisibility=hidden',
@@ -59,13 +68,15 @@ test_cxxflags = test_common_flags + [
'-Wcast-qual',
'-Wwrite-strings',
'-Wsign-compare',
'-Wcomma',
'-Wextra-semi',
'-Wheader-hygiene',
'-Winconsistent-missing-destructor-override',
'-Wunreachable-code-break',
'-Wunused',
'-Wused-but-marked-unused',
'-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',
]
if compiler.get_id() == 'clang'
@@ -101,6 +112,13 @@ if get_option('buildtype') != 'debug'
]
endif
if get_option('fuzzer')
fuzzer_flags = ['-fsanitize=fuzzer,address,undefined']
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(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')
@@ -136,13 +154,17 @@ 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)
@@ -188,6 +210,17 @@ 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
log = static_library(
'log',
'src/Log.cxx',
'src/LogBackend.cxx',
include_directories: inc,
)
log_dep = declare_dependency(
link_with: log,
)
sources = [
version_cxx,
'src/Main.cxx',
@@ -216,23 +249,23 @@ sources = [
'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',
@@ -277,6 +310,7 @@ sources = [
'src/TagSave.cxx',
'src/TagFile.cxx',
'src/TagStream.cxx',
'src/TagAny.cxx',
'src/TimePrint.cxx',
'src/mixer/Volume.cxx',
'src/PlaylistFile.cxx',
@@ -310,17 +344,22 @@ 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/apple')
subdir('src/lib/dbus')
subdir('src/lib/icu')
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')
@@ -335,6 +374,8 @@ subdir('src/lib/systemd')
subdir('src/lib/upnp')
subdir('src/lib/yajl')
subdir('src/lib/crypto')
subdir('src/fs')
subdir('src/config')
subdir('src/tag')
@@ -359,12 +400,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',
@@ -458,8 +506,10 @@ mpd = build_target(
sqlite_dep,
zeroconf_dep,
more_deps,
chromaprint_dep,
],
link_args: link_args,
build_by_default: not get_option('fuzzer'),
install: not is_android and not is_haiku,
)
@@ -495,10 +545,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

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

45
python/build/cmake.py Normal file

@@ -0,0 +1,45 @@
import subprocess
from build.project import Project
def configure(toolchain, src, build, args=()):
cross_args = []
if toolchain.is_windows:
cross_args.append('-DCMAKE_SYSTEM_NAME=Windows')
cross_args.append('-DCMAKE_RC_COMPILER=' + toolchain.windres)
configure = [
'cmake',
src,
'-DCMAKE_INSTALL_PREFIX=' + toolchain.install_prefix,
'-DCMAKE_BUILD_TYPE=release',
'-DCMAKE_C_COMPILER=' + toolchain.cc,
'-DCMAKE_CXX_COMPILER=' + toolchain.cxx,
'-DCMAKE_C_FLAGS=' + toolchain.cflags + ' ' + toolchain.cppflags,
'-DCMAKE_CXX_FLAGS=' + toolchain.cxxflags + ' ' + toolchain.cppflags,
'-GNinja',
] + cross_args + args
subprocess.check_call(configure, env=toolchain.env, cwd=build)
class CmakeProject(Project):
def __init__(self, url, md5, installed, configure_args=[],
**kwargs):
Project.__init__(self, url, md5, installed, **kwargs)
self.configure_args = configure_args
def configure(self, toolchain):
src = self.unpack(toolchain)
build = self.make_build_path(toolchain)
configure(toolchain, src, build, self.configure_args)
return build
def build(self, toolchain):
build = self.configure(toolchain)
subprocess.check_call(['ninja', 'install'],
cwd=build, env=toolchain.env)

@@ -4,13 +4,14 @@ 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.boost import BoostProject
libmpdclient = MesonProject(
'https://www.musicpd.org/download/libmpdclient/2/libmpdclient-2.18.tar.xz',
'4cb01e1f567e0169aca94875fb6e1200e7f5ce35b63a4df768ec1591fb1081fa',
'https://www.musicpd.org/download/libmpdclient/2/libmpdclient-2.19.tar.xz',
'158aad4c2278ab08e76a3f2b0166c99b39fae00ee17231bd225c5a36e977a189',
'lib/libmpdclient.a',
)
@@ -24,8 +25,8 @@ libogg = AutotoolsProject(
)
libvorbis = AutotoolsProject(
'http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.6.tar.xz',
'af00bb5a784e7c9e69f56823de4637c350643deedaf333d0fa86ecdba6fcb415',
'http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.7.tar.xz',
'b33cc4934322bcbf6efcbacf49e3ca01aadbea4114ec9589d1b1e9d20f72954b',
'lib/libvorbis.a',
[
'--disable-shared', '--enable-static',
@@ -111,9 +112,44 @@ 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',
],
)
wildmidi = CmakeProject(
'https://codeload.github.com/Mindwerks/wildmidi/tar.gz/wildmidi-0.4.3',
'498e5a96455bb4b91b37188ad6dcb070824e92c44f5ed452b90adbaec8eef3c5',
'lib/libWildMidi.a',
[
'-DBUILD_SHARED_LIBS=OFF',
'-DWANT_PLAYER=OFF',
'-DWANT_STATIC=ON',
],
base='wildmidi-wildmidi-0.4.3',
name='wildmidi',
version='0.4.3',
)
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.2.2.tar.xz',
'cb754255ab0ee2ea5f66f8850e1bd6ad5cac1cd855d0a2f4990fb8c668b0d29c',
'http://ffmpeg.org/releases/ffmpeg-4.3.1.tar.xz',
'ad009240d46e307b4e03a213a0f49c11b650e445b1f8be0dda2a9212b34d2ffb',
'lib/libavcodec.a',
[
'--disable-shared', '--enable-static',
@@ -341,8 +377,8 @@ ffmpeg = FfmpegProject(
)
curl = AutotoolsProject(
'http://curl.haxx.se/download/curl-7.69.1.tar.xz',
'03c7d5e6697f7b7e40ada1b2256e565a555657398e6c1fcfa4cb251ccd819d4f',
'http://curl.haxx.se/download/curl-7.73.0.tar.xz',
'7c4c7ca4ea88abe00fea4740dcf81075c031b1d0bb23aff2d5efde20a3c2408a',
'lib/libcurl.a',
[
'--disable-shared', '--enable-static',
@@ -393,11 +429,12 @@ libnfs = AutotoolsProject(
'--disable-utils', '--disable-examples',
],
base='libnfs-libnfs-4.0.0',
patches='src/lib/nfs/patches',
autoreconf=True,
)
boost = BoostProject(
'https://dl.bintray.com/boostorg/release/1.72.0/source/boost_1_72_0.tar.bz2',
'59c9b274bc451cf91a9ba1dd2c7fdcaf5d60b1b3aa83f2c9fa143417cc660722',
'https://dl.bintray.com/boostorg/release/1.74.0/source/boost_1_74_0.tar.bz2',
'83bfc1507731a0906e387fc28b7ef5417d591429e51e788417fe9ff025e116b1',
'include/boost/version.hpp',
)

@@ -91,7 +91,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=[],

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

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

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 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;

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -37,11 +37,15 @@
#include "fs/Traits.hxx"
#include "fs/FileSystem.hxx"
#include "fs/StandardDirectory.hxx"
#include "system/Error.hxx"
#include "util/RuntimeError.hxx"
#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 +59,7 @@
#include "neighbor/NeighborPlugin.hxx"
#endif
#include "encoder/Features.h"
#ifdef ENABLE_ENCODER
#include "encoder/EncoderList.hxx"
#include "encoder/EncoderPlugin.hxx"
@@ -65,9 +70,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 +79,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,8 +107,8 @@ 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"
@@ -145,15 +147,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 +208,9 @@ static void version(void)
"\n"
"Input plugins:\n"
" file"
#ifdef HAVE_URING
" io_uring"
#endif
#ifdef ENABLE_ARCHIVE
" archive"
#endif
@@ -255,7 +264,7 @@ static void version(void)
#endif
"\n");
exit(EXIT_SUCCESS);
std::exit(EXIT_SUCCESS);
}
static void PrintOption(const OptionDef &opt)
@@ -271,8 +280,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 +291,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 +305,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);
};

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

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 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@";

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 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

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 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;

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 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).

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 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);
}

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

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -25,7 +25,7 @@
#include "IdleFlags.hxx"
#include "util/ASCII.hxx"
#include <assert.h>
#include <cassert>
static const char *const idle_names[] = {
"database",

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

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 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,16 @@
#include "db/update/Service.hxx"
#include "storage/StorageInterface.hxx"
#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 +70,13 @@ Instance::~Instance() noexcept
#endif
}
void
Instance::OnStateModified() noexcept
{
if (state_file)
state_file->CheckModified();
}
Partition *
Instance::FindPartition(const char *name) noexcept
{
@@ -75,6 +87,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 +114,7 @@ Instance::GetDatabaseOrThrow() const
}
void
Instance::OnDatabaseModified()
Instance::OnDatabaseModified() noexcept
{
assert(database != nullptr);
@@ -101,15 +127,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 +150,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 +190,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();
}

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -53,6 +53,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 +99,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
@@ -119,11 +127,15 @@ struct Instance final
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,14 +143,27 @@ 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.
@@ -146,6 +171,8 @@ struct Instance final
gcc_pure
Partition *FindPartition(const char *name) noexcept;
void DeletePartition(Partition &partition) noexcept;
void BeginShutdownPartitions() noexcept;
#ifdef ENABLE_DATABASE
@@ -154,7 +181,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 +193,12 @@ struct Instance final
const Database &GetDatabaseOrThrow() const;
#endif
#ifdef ENABLE_SQLITE
bool HasStickerDatabase() noexcept {
return sticker_database != nullptr;
}
#endif
void BeginShutdownUpdate() noexcept;
#ifdef ENABLE_CURL
@@ -176,10 +209,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 +230,7 @@ private:
#endif
/* callback for #idle_monitor */
void OnIdle(unsigned mask);
void OnIdle(unsigned mask) noexcept;
};
#endif

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -34,8 +34,6 @@
#include "fs/XDG.hxx"
#include <sys/stat.h>
#include <string.h>
#include <assert.h>
#ifdef ENABLE_SYSTEMD_DAEMON
#include <systemd/sd-daemon.h>

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

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -22,8 +22,8 @@
#include "client/Client.hxx"
#include "fs/AllocatedPath.hxx"
#include "ls.hxx"
#include "util/UriUtil.hxx"
#include "util/ASCII.hxx"
#include "util/UriExtract.hxx"
#ifdef ENABLE_DATABASE
#include "storage/StorageInterface.hxx"
@@ -42,11 +42,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
@@ -80,9 +82,11 @@ 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());
}
#endif

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 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

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -19,162 +19,131 @@
#include "LogV.hxx"
#include "util/Domain.hxx"
#include "util/Exception.hxx"
#include <exception>
#include <cerrno>
#include <stdio.h>
#include <string.h>
#include <errno.h>
static constexpr Domain exception_domain("exception");
void
LogFormatV(const Domain &domain, LogLevel level,
const char *fmt, va_list ap) noexcept
LogFormatV(LogLevel level, const Domain &domain,
const char *fmt, std::va_list ap) noexcept
{
char msg[1024];
vsnprintf(msg, sizeof(msg), fmt, ap);
Log(domain, level, msg);
Log(level, domain, msg);
}
void
LogFormat(const Domain &domain, LogLevel level, const char *fmt, ...) noexcept
LogFormat(LogLevel level, const Domain &domain, const char *fmt, ...) noexcept
{
va_list ap;
std::va_list ap;
va_start(ap, fmt);
LogFormatV(domain, level, fmt, ap);
LogFormatV(level, domain, fmt, ap);
va_end(ap);
}
void
FormatDebug(const Domain &domain, const char *fmt, ...) noexcept
{
va_list ap;
std::va_list ap;
va_start(ap, fmt);
LogFormatV(domain, LogLevel::DEBUG, fmt, ap);
LogFormatV(LogLevel::DEBUG, domain, fmt, ap);
va_end(ap);
}
void
FormatInfo(const Domain &domain, const char *fmt, ...) noexcept
{
va_list ap;
std::va_list ap;
va_start(ap, fmt);
LogFormatV(domain, LogLevel::INFO, fmt, ap);
LogFormatV(LogLevel::INFO, domain, fmt, ap);
va_end(ap);
}
void
FormatDefault(const Domain &domain, const char *fmt, ...) noexcept
FormatNotice(const Domain &domain, const char *fmt, ...) noexcept
{
va_list ap;
std::va_list ap;
va_start(ap, fmt);
LogFormatV(domain, LogLevel::DEFAULT, fmt, ap);
LogFormatV(LogLevel::NOTICE, domain, fmt, ap);
va_end(ap);
}
void
FormatWarning(const Domain &domain, const char *fmt, ...) noexcept
{
va_list ap;
std::va_list ap;
va_start(ap, fmt);
LogFormatV(domain, LogLevel::WARNING, fmt, ap);
LogFormatV(LogLevel::WARNING, domain, fmt, ap);
va_end(ap);
}
void
FormatError(const Domain &domain, const char *fmt, ...) noexcept
{
va_list ap;
std::va_list ap;
va_start(ap, fmt);
LogFormatV(domain, LogLevel::ERROR, fmt, ap);
LogFormatV(LogLevel::ERROR, domain, fmt, ap);
va_end(ap);
}
void
LogError(const std::exception &e) noexcept
Log(LogLevel level, 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");
}
Log(level, exception_domain, GetFullMessage(e).c_str());
}
void
LogError(const std::exception &e, const char *msg) noexcept
Log(LogLevel level, 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");
}
LogFormat(level, exception_domain, "%s: %s", msg, GetFullMessage(e).c_str());
}
void
FormatError(const std::exception &e, const char *fmt, ...) noexcept
LogFormat(LogLevel level, const std::exception &e, const char *fmt, ...) noexcept
{
char msg[1024];
va_list ap;
std::va_list ap;
va_start(ap, fmt);
vsnprintf(msg, sizeof(msg), fmt, ap);
va_end(ap);
LogError(e, msg);
Log(level, e, msg);
}
void
LogError(const std::exception_ptr &ep) noexcept
Log(LogLevel level, 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");
}
Log(level, exception_domain, GetFullMessage(ep).c_str());
}
void
LogError(const std::exception_ptr &ep, const char *msg) noexcept
Log(LogLevel level, 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);
}
LogFormat(level, exception_domain, "%s: %s", msg,
GetFullMessage(ep).c_str());
}
void
FormatError(const std::exception_ptr &ep, const char *fmt, ...) noexcept
LogFormat(LogLevel level, const std::exception_ptr &ep, const char *fmt, ...) noexcept
{
char msg[1024];
va_list ap;
std::va_list ap;
va_start(ap, fmt);
vsnprintf(msg, sizeof(msg), fmt, ap);
va_end(ap);
LogError(ep, msg);
Log(level, ep, msg);
}
void
LogErrno(const Domain &domain, int e, const char *msg) noexcept
{
LogFormat(domain, LogLevel::ERROR, "%s: %s", msg, strerror(e));
LogFormat(LogLevel::ERROR, domain, "%s: %s", msg, strerror(e));
}
void
@@ -184,7 +153,7 @@ LogErrno(const Domain &domain, const char *msg) noexcept
}
static void
FormatErrnoV(const Domain &domain, int e, const char *fmt, va_list ap) noexcept
FormatErrnoV(const Domain &domain, int e, const char *fmt, std::va_list ap) noexcept
{
char msg[1024];
vsnprintf(msg, sizeof(msg), fmt, ap);
@@ -195,7 +164,7 @@ FormatErrnoV(const Domain &domain, int e, const char *fmt, va_list ap) noexcept
void
FormatErrno(const Domain &domain, int e, const char *fmt, ...) noexcept
{
va_list ap;
std::va_list ap;
va_start(ap, fmt);
FormatErrnoV(domain, e, fmt, ap);
va_end(ap);
@@ -206,7 +175,7 @@ FormatErrno(const Domain &domain, const char *fmt, ...) noexcept
{
const int e = errno;
va_list ap;
std::va_list ap;
va_start(ap, fmt);
FormatErrnoV(domain, e, fmt, ap);
va_end(ap);

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -28,16 +28,38 @@
class Domain;
void
Log(const Domain &domain, LogLevel level, const char *msg) noexcept;
Log(LogLevel level, const Domain &domain, const char *msg) noexcept;
gcc_printf(3,4)
void
LogFormat(const Domain &domain, LogLevel level, const char *fmt, ...) noexcept;
LogFormat(LogLevel level, const Domain &domain, const char *fmt, ...) noexcept;
void
Log(LogLevel level, const std::exception &e) noexcept;
void
Log(LogLevel level, const std::exception &e, const char *msg) noexcept;
gcc_printf(3,4)
void
LogFormat(LogLevel level, const std::exception &e,
const char *fmt, ...) noexcept;
void
Log(LogLevel level, const std::exception_ptr &ep) noexcept;
void
Log(LogLevel level, const std::exception_ptr &ep, const char *msg) noexcept;
gcc_printf(3,4)
void
LogFormat(LogLevel level, const std::exception_ptr &ep,
const char *fmt, ...) noexcept;
static inline void
LogDebug(const Domain &domain, const char *msg) noexcept
{
Log(domain, LogLevel::DEBUG, msg);
Log(LogLevel::DEBUG, domain, msg);
}
gcc_printf(2,3)
@@ -47,7 +69,7 @@ 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)
@@ -55,19 +77,19 @@ 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;
FormatNotice(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)
@@ -77,28 +99,47 @@ 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 &e) noexcept
{
Log(LogLevel::ERROR, e);
}
void
LogError(const std::exception &e, const char *msg) noexcept;
inline void
LogError(const std::exception &e, const char *msg) noexcept
{
Log(LogLevel::ERROR, e, msg);
}
gcc_printf(2,3)
void
FormatError(const std::exception &e, const char *fmt, ...) noexcept;
template<typename... Args>
inline void
FormatError(const std::exception &e, const char *fmt, Args&&... args) noexcept
{
LogFormat(LogLevel::ERROR, e, fmt, std::forward<Args>(args)...);
}
void
LogError(const std::exception_ptr &ep) noexcept;
inline void
LogError(const std::exception_ptr &ep) noexcept
{
Log(LogLevel::ERROR, ep);
}
void
LogError(const std::exception_ptr &ep, const char *msg) noexcept;
inline void
LogError(const std::exception_ptr &ep, const char *msg) noexcept
{
Log(LogLevel::ERROR, ep, msg);
}
gcc_printf(2,3)
void
FormatError(const std::exception_ptr &ep, const char *fmt, ...) noexcept;
template<typename... Args>
inline void
FormatError(const std::exception_ptr &ep,
const char *fmt, Args&&... args) noexcept
{
LogFormat(LogLevel::ERROR, ep, fmt, std::forward<Args>(args)...);
}
gcc_printf(2,3)
void

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 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;
@@ -120,7 +122,7 @@ ToSysLogLevel(LogLevel log_level) noexcept
case LogLevel::INFO:
return LOG_INFO;
case LogLevel::DEFAULT:
case LogLevel::NOTICE:
return LOG_NOTICE;
case LogLevel::WARNING:
@@ -176,7 +178,7 @@ 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, const char *msg) noexcept
{
#ifdef ANDROID
__android_log_print(ToAndroidLogLevel(level), "MPD",

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

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 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 {

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

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 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.

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -22,10 +22,10 @@
#include "Log.hxx" // IWYU pragma: export
#include <stdarg.h>
#include <cstdarg>
void
LogFormatV(const Domain &domain, LogLevel level,
const char *fmt, va_list ap) noexcept;
LogFormatV(LogLevel level, const Domain &domain,
const char *fmt, std::va_list ap) noexcept;
#endif /* LOG_H */

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -27,30 +27,30 @@
#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 "fs/AllocatedPath.hxx"
#include "fs/Config.hxx"
#include "playlist/PlaylistRegistry.hxx"
#include "zeroconf/ZeroconfGlue.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 +58,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 +83,7 @@
#endif
#ifdef ENABLE_SQLITE
#include "sticker/StickerDatabase.hxx"
#include "sticker/Database.hxx"
#endif
#ifdef ENABLE_ARCHIVE
@@ -95,6 +96,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 +109,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 +129,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
@@ -166,14 +163,15 @@ glue_mapper_init(const ConfigData &config)
#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 +181,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 +212,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 +279,21 @@ 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) {
FormatWarning(config_domain, "buffer size %lu is too small, using %lu bytes instead",
(unsigned long)result,
(unsigned long)MIN_BUFFER_SIZE);
result = MIN_BUFFER_SIZE;
}
return result;
});
} else
buffer_size = DEFAULT_BUFFER_SIZE;
@@ -306,35 +307,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
@@ -354,56 +346,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 +370,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 +381,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, 100);
instance->client_list = new ClientList(max_clients);
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 +415,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 +431,26 @@ 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.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,37 +460,42 @@ 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);
ZeroconfInit(raw_config, instance.event_loop);
#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,
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));
#else
@@ -581,7 +509,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 +518,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 +533,98 @@ mpd_main_after_fork(const ConfigData &raw_config, const Config &config)
/* cleanup */
instance->BeginShutdownUpdate();
if (instance->state_file != nullptr) {
instance->state_file->Write();
delete instance->state_file;
}
instance.BeginShutdownUpdate();
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.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();
}
#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[]) noexcept
{
AtScopeExit() { log_deinit(); };
try {
MainOrThrow(argc, argv);
return EXIT_SUCCESS;
} catch (...) {
LogError(std::current_exception());
return EXIT_FAILURE;
}
}
int
main(int argc, char *argv[]) noexcept
{
#ifdef _WIN32
return win32_main(argc, argv);
#else
return mpd_main(argc, argv);
#endif
}
#endif

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 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

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 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;

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

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

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 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) {

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

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 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;

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 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;
@@ -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

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

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

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 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

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -25,11 +25,9 @@
#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.

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -20,24 +20,33 @@
#include "config.h"
#include "Partition.hxx"
#include "Instance.hxx"
#include "Log.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 +55,51 @@ 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;
FormatDebug(cache_domain, "Prefetch '%s'", uri);
try {
cache.Prefetch(uri);
} catch (...) {
FormatError(std::current_exception(),
"Prefetch '%s' failed", uri);
}
}
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 +115,7 @@ Partition::UpdateEffectiveReplayGainMode()
#ifdef ENABLE_DATABASE
const Database *
Partition::GetDatabase() const
Partition::GetDatabase() const noexcept
{
return instance.GetDatabase();
}
@@ -80,7 +127,7 @@ Partition::GetDatabaseOrThrow() const
}
void
Partition::DatabaseModified(const Database &db)
Partition::DatabaseModified(const Database &db) noexcept
{
playlist.DatabaseModified(db);
EmitIdle(IDLE_DATABASE);
@@ -89,7 +136,7 @@ Partition::DatabaseModified(const Database &db)
#endif
void
Partition::TagModified()
Partition::TagModified() noexcept
{
auto song = pc.LockReadTaggedSong();
if (song)
@@ -103,31 +150,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 +202,7 @@ Partition::OnBorderPause() noexcept
}
void
Partition::OnMixerVolumeChanged(gcc_unused Mixer &mixer, gcc_unused int volume)
Partition::OnMixerVolumeChanged(Mixer &, int) noexcept
{
InvalidateHardwareVolume();
@@ -160,7 +211,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();

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -30,9 +30,10 @@
#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>
@@ -40,6 +41,7 @@ struct Instance;
class MultipleOutputs;
class SongLoader;
class ClientListener;
class Client;
/**
* A partition of the Music Player Daemon. It is a separate unit with
@@ -56,6 +58,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 +83,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);
}
@@ -108,11 +137,11 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
playlist.DeleteRange(pc, start, end);
}
void StaleSong(const char *uri) {
void StaleSong(const char *uri) noexcept {
playlist.StaleSong(pc, uri);
}
void Shuffle(unsigned start, unsigned end) {
void Shuffle(unsigned start, unsigned end) noexcept {
playlist.Shuffle(pc, start, end);
}
@@ -142,7 +171,7 @@ struct Partition final : QueueListener, PlayerListener, MixerListener {
playlist.SetPriorityId(pc, song_id, priority);
}
void Stop() {
void Stop() noexcept {
playlist.Stop(pc);
}
@@ -174,27 +203,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 +232,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 +240,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 +248,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 +266,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 +286,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

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -22,14 +22,15 @@
#include "config/Param.hxx"
#include "config/Data.hxx"
#include "config/Option.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 = ',';
@@ -54,35 +55,25 @@ static unsigned local_permissions;
#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)
{
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;
string = comma + 1;
}
for (const auto i : IterableSplitString(string, PERMISSION_SEPARATOR))
if (!i.empty())
permission |= ParsePermission(i);
return permission;
}
@@ -90,48 +81,44 @@ static unsigned parsePermissions(const char *string)
void
initPermissions(const ConfigData &config)
{
unsigned permission;
permission_default = PERMISSION_READ | PERMISSION_ADD |
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.insert(std::make_pair(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
}
int getPermissionFromPassword(char const* password, unsigned* permission)
int
getPermissionFromPassword(const char *password, unsigned *permission) noexcept
{
auto i = permission_passwords.find(password);
if (i == permission_passwords.end())
@@ -141,7 +128,8 @@ int getPermissionFromPassword(char const* password, unsigned* permission)
return 0;
}
unsigned getDefaultPermissions(void)
unsigned
getDefaultPermissions() noexcept
{
return permission_default;
}

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -30,10 +30,11 @@ static constexpr unsigned PERMISSION_ADD = 2;
static constexpr unsigned PERMISSION_CONTROL = 4;
static constexpr unsigned PERMISSION_ADMIN = 8;
int getPermissionFromPassword(char const* password, unsigned* permission);
int
getPermissionFromPassword(const char *password, unsigned *permission) noexcept;
unsigned
getDefaultPermissions();
getDefaultPermissions() noexcept;
#ifdef HAVE_UN
unsigned

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -25,7 +25,8 @@
#include "util/StringStrip.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",

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

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

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

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 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 &

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

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -22,11 +22,6 @@
#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"
#define SONG_FILE "file: "
#define SONG_TIME "Time: "

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 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 @@
#ifndef MPD_PLAYLIST_PRINT_HXX
#define MPD_PLAYLIST_PRINT_HXX
#include <stdint.h>
#include <cstdint>
struct playlist;
class SongFilter;

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 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)

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

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -27,10 +27,20 @@
* that this plugin is unavailable. It will be disabled, and MPD can
* continue initialization.
*/
class PluginUnavailable final : public std::runtime_error {
class PluginUnavailable : public std::runtime_error {
public:
explicit PluginUnavailable(const char *msg)
:std::runtime_error(msg) {}
using std::runtime_error::runtime_error;
};
/**
* Like #PluginUnavailable, but denotes that the plugin is not
* available because it was not explicitly enabled in the
* configuration. The message may describe the necessary steps to
* enable it.
*/
class PluginUnconfigured : public PluginUnavailable {
public:
using PluginUnavailable::PluginUnavailable;
};
#endif

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

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

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

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

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -19,13 +19,12 @@
#include "ReplayGainGlobal.hxx"
#include "ReplayGainConfig.hxx"
#include "config/Param.hxx"
#include "config/Data.hxx"
#include "util/RuntimeError.hxx"
#include <assert.h>
#include <stdlib.h>
#include <math.h>
#include <cassert>
#include <cmath>
#include <cstdlib>
#include <stdexcept>
static float
ParsePreamp(const char *s)
@@ -33,25 +32,14 @@ ParsePreamp(const char *s)
assert(s != nullptr);
char *endptr;
float f = strtod(s, &endptr);
float f = std::strtof(s, &endptr);
if (endptr == s || *endptr != '\0')
throw std::invalid_argument("Not a numeric value");
if (f < -15 || f > 15)
if (f < -15.0f || f > 15.0f)
throw std::invalid_argument("Number must be between -15 and 15");
return pow(10, f / 20.0);
}
static float
ParsePreamp(const ConfigParam &p)
{
try {
return ParsePreamp(p.value.c_str());
} catch (...) {
std::throw_with_nested(FormatRuntimeError("Failed to parse line %i",
p.line));
}
return std::pow(10.0f, f / 20.0f);
}
ReplayGainConfig
@@ -59,13 +47,17 @@ LoadReplayGainConfig(const ConfigData &config)
{
ReplayGainConfig replay_gain_config;
const auto *param = config.GetParam(ConfigOption::REPLAYGAIN_PREAMP);
if (param)
replay_gain_config.preamp = ParsePreamp(*param);
replay_gain_config.preamp = config.With(ConfigOption::REPLAYGAIN_PREAMP, [](const char *s){
return s != nullptr
? ParsePreamp(s)
: 1.0f;
});
param = config.GetParam(ConfigOption::REPLAYGAIN_MISSING_PREAMP);
if (param)
replay_gain_config.missing_preamp = ParsePreamp(*param);
replay_gain_config.missing_preamp = config.With(ConfigOption::REPLAYGAIN_MISSING_PREAMP, [](const char *s){
return s != nullptr
? ParsePreamp(s)
: 1.0f;
});
replay_gain_config.limit = config.GetBool(ConfigOption::REPLAYGAIN_LIMIT,
ReplayGainConfig::DEFAULT_LIMIT);

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

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 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 "ReplayGainInfo.hxx"
#include "ReplayGainConfig.hxx"
#include <math.h>
#include <cmath>
float
ReplayGainTuple::CalculateScale(const ReplayGainConfig &config) const noexcept
@@ -28,13 +28,13 @@ ReplayGainTuple::CalculateScale(const ReplayGainConfig &config) const noexcept
float scale;
if (IsDefined()) {
scale = pow(10.0, gain / 20.0);
scale = std::pow(10.0f, gain / 20.0f);
scale *= config.preamp;
if (scale > 15.0)
scale = 15.0;
if (scale > 15.0f)
scale = 15.0f;
if (config.limit && scale * peak > 1.0)
scale = 1.0 / peak;
if (config.limit && scale * peak > 1.0f)
scale = 1.0f / peak;
} else
scale = config.missing_preamp;

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

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -19,9 +19,9 @@
#include "ReplayGainMode.hxx"
#include <cassert>
#include <stdexcept>
#include <assert.h>
#include <string.h>
const char *

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -22,7 +22,7 @@
#include "util/Compiler.h"
#include <stdint.h>
#include <cstdint>
enum class ReplayGainMode : uint8_t {
OFF,

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -19,9 +19,9 @@
#include "SingleMode.hxx"
#include <cassert>
#include <stdexcept>
#include <assert.h>
#include <string.h>
const char *

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -22,7 +22,7 @@
#include "util/Compiler.h"
#include <stdint.h>
#include <cstdint>
enum class SingleMode : uint8_t {
OFF,

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2020 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -26,7 +26,7 @@
#include "PlaylistError.hxx"
#include "config.h"
#include <assert.h>
#include <cassert>
#ifdef ENABLE_DATABASE
@@ -54,11 +54,11 @@ SongLoader::LoadFile(const char *path_utf8, Path path_fs) const
{
#ifdef ENABLE_DATABASE
if (storage != nullptr) {
const char *suffix = storage->MapToRelativeUTF8(path_utf8);
if (suffix != nullptr)
const auto suffix = storage->MapToRelativeUTF8(path_utf8);
if (suffix.data() != nullptr)
/* this path was relative to the music
directory - obtain it from the database */
return LoadFromDatabase(suffix);
return LoadFromDatabase(std::string(suffix).c_str());
}
#endif

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

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