When rpc_reconnect_requeue() gets called from inside nfs_service(),
the NfsInputStream can stall completely because the old socket has
been unregistered from epoll automatically, but the new one has never
been registered. Therefore, nfs_service() will never be called again.
This kludge attempts to detect this condition by checking
nfs_which_events()==POLLOUT.
https://bugs.musicpd.org/view.php?id=4081
If the base class is not accessible, the "catching" the base class
won't work. This caused the fatal error:
terminate called after throwing an instance of 'LibmpdclientError'
Each close/open cycle resets the Filter's state, because a new Filter
instance is being created. That results in the serials
(replay_gain_serial and other_replay_gain_serial) being out of sync
with the internal ReplayGainFilter state.
So instead of initializing those serials once, we need to initialize
them each time we create new ReplayGainFilter instances, i.e. in
OpenFilter().
https://bugs.musicpd.org/view.php?id=4632
Previously, there was no special code to convert stereo to
multi-channel. The generic solution for this was to convert to mono,
and then copy the result to all channels. That's a pretty bad
solution, but at least something which always renders audio. MPD does
something, instead of failing.
Now that MPD has proper support for multi-channel (by defining the
channel order), we can do better than that. It is a (somewhat) common
case to play back stereo music on a DAC which can only do
multi-channel. The best approach here is to copy the stereo channels
to front-left and front-right, and apply the "silence" pattern to all
other channels.
If the input AudioFormat changes but the out_audio_format doesn't
change (e.g. because there is a fixed "format" setting in this
"audio_output" section), the ConvertFilter needs to be reconfigured.
This didn't happen, resulting in awful static noise after changing
songs.
This method is used by DecoderControl::IsCurrentSong(), which is used
by the player thread to check whether the current decoder instance can
be reused to seek. When switching to another song in the same CUE
sheet, previously DetachedSong::IsSame() returned true, and thus the
old decoder instance was used for the new song, not considering the
new end_time. This led to the old decoder quickly quitting.
This way, we have four periods instead of the default of two. With
only two periods, we don't get woken up often enough, and we
frequently encounter buffer overruns. With four periods, we have more
time to breathe, and the buffer overruns magically disappear.
The byte order of DSD_U32 was wrong from the start. The oldest bits
must be in the MSB, not in the LSB, according to
snd_pcm_format_descriptions in alsa-lib.
DSD_U32 packs four bytes instead of one large "sample", thus the
sample rate is one quarter of the input sample rate. This fixes a
rather critical DSD_U32 playback problem.
Changed AlsaMixerPlugin to use the get and set normalized functions from volume_mapping of alsa-utils/alsamixer
Changed volume_mapping set volume to be for all channels and not per channel
added volume_mapping files to Makefile.am
Without this, the pipe would run empty very often, which may result in
an xrun if the roundtrip to the PlayerThread and back takes too long.
By waking up the PlayerThread before the pipe runs empty, we make MPD
much more latency tolerant, which is a major optimization.
The user unit omits the "ProtectKernelModules" setting which fails
with modular kernels:
Failed at step CAPABILITIES spawning /usr/bin/mpd: Operation not permitted
It is unfortunate that systemd (version 232) is unable to reduce its
own capabilities, because this requires us to split system and user
units.
https://bugs.musicpd.org/view.php?id=4608