This commit addresses issues #2226 and MusicPlayerDaemon/ncmpc#95.
MPD and sndio volume ranges being different, the formula to transform a
value from one set to the other is in the form of `(a * x + b) / c`
where:
- a = output set max value
- b = adjustment term
- c = input set max value
Previous calculation formula had `b = 0`, scaling values too low and
rendering increment impossible. Having `b = out_maxval / 2` balances the
transformation, ensuring a better spread of values across the output
range.
Closes#2226
MPD stopped building since fmt 11.1.0; see
<https://github.com/fmtlib/fmt/issues/4304>. The first commit
fixing this was 9db7144, followed by 5de0909 (both on the
unstable branch).
This commit removes what the author believes to be the remaining
uses in the MPD codebase.
When compiling with libfmt-11.1.0 and newer the following compile errors occur:
In file included from ../src/decoder/DecoderPrint.cxx:23:
../src/client/Response.hxx: In instantiation of 'bool Response::Fmt(const S&, Args&& ...) [with S = decoder_plugin_print(Response&, const DecoderPlugin&)::<lambda()>::FMT_COMPILE_STRING; Args = {const char* const&}]':
../src/decoder/DecoderPrint.cxx:38:7: required from here
38 | r.Fmt(FMT_STRING("plugin: {}\n"), plugin.name);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../src/client/Response.hxx:86:28: error: cannot convert 'const decoder_plugin_print(Response&, const DecoderPlugin&)::<lambda()>::FMT_COMPILE_STRING' to 'fmt::v11::string_view' {aka 'fmt::v11::basic_string_view<char>'}
86 | return VFmt(format_str,
| ~~~~^~~~~~~~~~~~
87 | fmt::make_format_args(args...));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../src/client/Response.hxx:81:36: note: initializing argument 1 of 'bool Response::VFmt(fmt::v11::string_view, fmt::v11::format_args)'
81 | bool VFmt(fmt::string_view format_str, fmt::format_args args) noexcept;
| ~~~~~~~~~~~~~~~~~^~~~~~~~~~
../src/client/Response.hxx: In instantiation of 'bool Response::Fmt(const S&, Args&& ...) [with S = decoder_plugin_print(Response&, const DecoderPlugin&)::<lambda()>::FMT_COMPILE_STRING; Args = {const char* const&}]':
The error is due to the use of FMT_STRING. The libfmt team shared the following:
The correct way of using FMT_STRING is to wrap a format string when passing to a
function with compile-time checks (i.e. that takes format_string) as documented
in https://fmt.dev/11.1/api/#legacy-compile-time-checks.
Noting that FMT_STRING is a legacy API and has been superseded by consteval-based
API starting from version 8: https://github.com/fmtlib/fmt/releases/tag/8.0.0. It
looks like MPD is trying to emulate {fmt}'s old way of implementing compile-time
checks which was never properly documented because it was basically a hack. So the
correct fix is to switch to format_string and, possibly, remove usage of FMT_STRING.
The old way of doing compile-time checks (fmt::make_args_checked) was documented
in https://fmt.dev/7.1/api.html#argument-lists but it looks like MPD is not using
that API so the problematic uses of FMT_STRING have no effect and can just be removed.
The FMT_STRING has been removed in this change based on the fmt-7.1 API and now MPD is
successfully compile against the current libfmt-11.1.0 which highlighted the issue that
had been present in the codebase as it is now triggering the error, is legacy and was
not using the API for which FMT_STRING was aligned with.
This allows keeping the ALSA PCM open even if playback is paused. As
a side effect, this allows using the "always_on" option with ALSA
outputs, because "always_on" pauses the output.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1623
There were a few macOS related bug reports on the bug tracker which
have been open for years without a volunteer caring for them. The
GitHub actions build has also been broken for a long time due to bugs
in the ancient LLVM toolchain shipped with macOS, making macOS an
unsuitable non-Linux target for testing MPD's portability.
All of this makes macOS support an annoying liability for me. To
avoid more frustration, I'm hereby dropping macOS support completely
from MPD. Maybe this causes enough pain for a new maintainer to
spawn, but maybe nobody cares, so... let's see.
After all these years, we had this as a field but there was never a
way to change the value. So let's just hard-code it until we actually
have a reason to make it variable at runtime.
It is not possible to prepare an ALSA device when it is is state
SND_PCM_STATE_OPEN; it is necessary to set the hardware parameters
first.
This pedantic commit corrects that error. Note that in practice
this code path cannot be encountered because MPD always sets the
hardware parameters before attempting to start playback.
It is possible that an underrun may occur in the ALSA output
device while MPD is draining its own internal buffer. If this
happens then MPD stops playback, reporting the error EPIPE.
This commit attempts to recover the ALSA device instead of
stopping playback, so that the drain can complete and the next
song in the play queue is played.
It was surprising that Read() was non-blocking, but there was no
blocking version of it. Let's make the non-blocking behavior explicit
and change Read() to be blocking.
In order to find existing callers easily with compiler errors, this
also refactors Read()/Write() to take a std::span parameter.