Deactivate the stream in Cancel(). This fixes stuttering after a
manual song change by refilling the whole ring buffer before
reactivating the stream.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1354
Clear not only MPD's ring buffer, but also libpipewire's buffers, to
avoid playing some audio from the previous song after a manual song
change.
Fixes part 1 of https://github.com/MusicPlayerDaemon/MPD/issues/1354
Removing the LockHasClients(); this code was copied from the "httpd"
output plugin, but unlike "httpd", the SnapCast output plugin does not
feed silence while paused, so we need to implement a delay to avoid
busy-looping the CPU.
As a side effect, this eliminates the suttering after resuming
playback, because the timer now gets reset even if there is a client.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1394
Since PipeWire 0.3.53, there is no control name anymore, therefore the
name check doesn't work anymore, breaking volume change events.
This obsoletes the crash bug fix in commit 2ee57f9b0d
If the PipeWire output has not yet been enabled and no thread_loop has
been created yet, a nullptr dereference in SetVolume() was possible
because nullptr was passed to pw_thread_loop_lock().
This fixes a std::terminate() crash in the CURL storage plugin when
PropfindOperation::OnHeaders() throws an exception after receiving a
non-207 status.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1559
Previous versions of MPD would, on parameter change, set the PipeWire
volume before clearing the restore_volume flag, causing the call to
short circuit and do nothing. Instead, clear the flag before the call.
Move audio output state check ahead of mixer check and force volume
applying even for disabled software mixed outputs.
This fixes incorrect software mixer volume that used to occur when
volume was changed while output being disabled.
This is easily reproduced with following sequence of commands on
multi-output software mixed MPD setup.
mpc volume 38; mpc disable 3; mpc volume 88; mpc enable 3
On current MPD, following commands would result in output 3 playing at
volume 38, while all other enabled outputs would play at volume
88. Moreover, global volume would display average of outputs real
volumes. In my case, it's 75.
After applying this patch, following commands would produce expected
behavior. All outputs play at expected (88) volume. And volume is
correctly displayed as 88.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1423
Signed-off-by: Vitaly Ostrosablin tmp6154@yandex.ru
Signed-off-by: Vitaly Ostrosablin <tmp6154@yandex.ru>
Wasapi output plugin won't start playing after being paused
The cause is that the scope guard in the WASAPI work thread
(WasapiOutputPlugin.cxx, function WasapiOutputThread::Work(), in the
while (true) loop) is set up too 'late' in the execution. There is one
condition ("if (data_in_frames >= buffer_size_in_frames)") when it is
hit, the loop will continue without executing the scope guard. This
scope guard is responsible for emptying the buffer again, and if the
buffer is not emptied, the above mentioned condition will stay true.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1451
This reverts commit 552c30eae4.
It has caused various problems; for example, MPD wasn't able to write
the pid_file (which was already mitigated by commit a4e4217204).
And apparently, the socket file created in the same directory by
mpd.socket disappears when mpd.service (re)creates the directory. I
could not reproduce this problem with 247.3, but maybe this is a bug
in older systemd versions?
Until we figure out why this happens, let's remove the
RuntimeDirectory directive. A future MPD version may be launched as
regular user, not as root, which will eliminate one major problem with
RuntimeDirectory.
Commit 552c30eae caused problems for those people who still had a
"pid_file" setting (even though that is obsolete with systemd),
because now /run/mpd is owned by root:root (our mpd.service has no
User=mpd directive, so systemd starts MPD as root).
To work around this problem, and to be able to keep
RuntimeDirectory=mpd (which solved a problem of other MPD users), the
best compromise seems to just ignore the "pid_file" setting when it is
of no use.
Unlike GetFilenameSuffix(), uri_get_suffix() removes the query string
first, which breaks file names with question marks in the name.
Therefore, uri_get_suffix() shall only be applied to remote URIs.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1316
Without clearing the "uri" field, the next Open() call attempts to
reuse the old InputStream, but it has already been closed, so Open()
always returns nullptr.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1300
With libfmt versions older than 7, this leads to an endless recursion
between Error() and FmtError(), resulting in a crash due to stack
overflow. D'oh!
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1295
During the libfmt migration, I converted "%1.3f" to just "{:1.3}"
without the "f" suffix, but libfmt defaults to scientific notation,
which can break some MPD clients.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1291
This replaces the output parameter (which is bad API design). As a
side effect, it fixes the bad [[gnu::pure]] attribute added by commit
a636d2127 which caused optimizing compilers to miscompile calls to
that function. "Pure" functions can be assumed to have no output
arguments, so the compiler can assume the function doesn't modify
them.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1282
Fixes https://github.com/MusicPlayerDaemon/MPD/discussions/1281
The problem occurred when there was libfmt-dev installed, but it was
too old (e.g. on Debian Buster), and Meson used the wrap fallback.
Those internal MPD libraries where the libfmt dependency was not
declared were still using the old system libfmt headers, which are not
ABI-compatible with MPD's own libfmt build.
From the feature request: "I generally like to have crossfade on, but
when it happens during such short tracks (e.g. 20 seconds or less) it
doesn't really sound good as those tracks are not really meant to be
crossfaded and intended to act as a bridge on their own."
Sounds reasonable. This commit doesn't add an option, but hard-codes
the limit to 20 seconds. If it turns out that users want to have it
configurable, we can still add the option.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1184
A similar feature was present long ago in MPD, but was deprecated in
version 0.16 because the implementation was broken. This commit
re-adds the feature in a way that's well-defined and not broken.
Close https://github.com/MusicPlayerDaemon/MPD/issues/1221
If DetectFilterOutputFormat() fails to determine the output format,
insert an "aformat" filter which attempts to force a specific output
format.
Fixes part 2 of of https://github.com/MusicPlayerDaemon/MPD/issues/1235
If UpdateStreamTag() gets called while an initial seek is pending, the
result will never be submitted to a MusicChunk. By avoiding the
UpdateStreamTag() call in that case (by moving UpdateStreamTag() to
after the PrepareInitialSeek() check), the song_tag is preserved until
UpdateStreamTag() is called again from SubmitData().
This fixes missing tags in the "httpd" output.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1137
Explanation
This adds support for DOP using the PcmExport function if the macro
ENABLE_DSD is defined. If enabled within the config-file using "dop",
the boolean dop_setting will be true. If DSD input is encountered and
the setting is on, it is checked whether the oss-device supports the
required samplerate. If that is the case, dop_active is set to true
and conversion of the input is prevented. If the sample rate is not
supported, conversion to S32 is requested. When playing back, the
PcmExport is used to pack the incoming stream into PCM. Reasoning
This is required for OSs without the required driver support for
native DSD playback that also have no ALSA. Mainly *BSD users are the
target audience for this functionality, as ALSA here is only a proxy
without full functionality. Requirements
DAC that supports the DOP standard
Building with OSS, DSD and S32-Format
Supported Formats / Required PCM Formats
DSF, DFF and WavPack-DSD will work.
DSD64, 1 Channel -> S24:176.4kHz (untested, lack of time / missing samples)
DSD64, 2 Channel -> S24:352.8kHz
DSD64, 4 Channel -> S24:705.6kHz (untested, lmissing equipment)
DSD128, 1 Channel -> S24:352.8kHz (untested, lack of time / missing samples)
DSD128, 2 Channel -> S24:705.6kHz
DSD256, 1 Channel -> S24:705.6kHz (untested, lack of time / missing samples)
Changes
inclusion of required files
adding new domain for logging
adding dop_satisfied private function
adding required member variables for storing dop state and for dop-packing
adding dop boolean parameter to many functions that are required to act a little differently when dop is active
Testing
This has been tested to work with a Sabaj Da2 on FreeBSD, where the
red status indicator LED clearly shows that DSD playback is taking
place, instead of purple for "hi-res" which is seen when converting.
Issues
I have not tested this with S24 and right now AFMT_S32_NE is
required. If not defined, ENABLE_DSD will be undef'ed. This will be
addressed in a bit, however no DAC which supports DOP but not 32Bit is
known to me. Also, AFMT_S32_NE is not defined when building on FreeBSD
which is why this is just blatantly defined in the file at the moment.
Additionally, the new dop-option is not added into any documentation
whatsoever.
We need this even when AFMT_S24_PACKED is not available, for the
correct channel order in multi-channel files. Internally, MPD uses
FLAC channel order, but OSS uses the same channel order as ALSA.
Also, use RemoveAll() instead of directly clearing TagBuilder::items in
most cases, as its elements represent references that must be released.
Closes#1023
ProxyInputStream::Read() assigns the `offset` field, which is the
wrong offset because it does not consider Icy metadata removed from
the stream. Therefore, after every ProxyInputStream::Read() call,
IcyInputStream::Read() needs to override this offset. This was
missing at the end of the stream, when Read()==0.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1216
With the default value CURLAUTH_ANY, libcurl needs to probe for
authentication methods first, and only the second request will have an
Authorization header.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1155
This enables the JACK output plugin on Windows, but doesn't link
against libjack64.dll, instead loads the DLL at runtime with
LoadLibrary(). This kludge avoids the extremely fragile JACK shared
memory protocol by using the system's libjack64.dll, without requiring
the same DLL at build time.
This reverts commit 1532983fb5. This
optimization was bad because now all strings match if they are a
prefix of another string, and this caused collisions in the tag string
pool, corrupting the database.
The current http output doesn't provide a header for cross-origin support. This prevents to use the mpd http stream directly from an other webapplication due the origin from the webpage differs from then the audio stream.
The fix is to add the following header to the http response:
Access-Control-Allow-Origin: *
This commit adds some tags that are (mostly) interesting for listeners
of classical music.
Ensemble
--------
This is an ensemble that is playing the music, such as Wiener
Philharmoniker. The tag can be used to distinguish the ensemble from the
conductor, composer, soloist, and ensemble, that are generally all in
the "ARTIST" tag.
Movement
-------
The movement number and movement (name) of this track, i.e. "II" and
"Allegro".
ComposerSort
------------
Allows us to look for Beethoven's 9th under B, for Beethoven, not L for
Ludwig.
Location
--------
This is the location of the recording, e.g. "Wiener Musikverein".
ParseTimePoint.
%Z is a glibc extension to strptime, and is a no-op there, due to the
mapping between timezone names and their definition (especially when the
name comes from a different machine) being ambiguous / impossible. Time
in HTTP headers is guaranteed to be UTC.
Passing an unknown format to strptime() implementations that don't
support it will generally cause them to return NULL, which will lead to
ParseTimePoint throwing an exception and ParseTimeStamp using an
unnecessary fallback.
Since the timezone name goes at the end of the string, we don't need to
use %Z to skip it (could be an issue in a different time stamp format),
so simply removing %Z works best.
If the constructor moves from an ExportedSong instance which refers to
somebody else's "Tag" instance, the newly constructed instance will
instead refer to its own empty "tag_buffer" field. This broke
SimpleDatabase::GetSong(), i.e. all songs on the queue restored from
the state file or added using the "addid" command.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1089
The "move" command doesn't allow open-ended ranges because they don't
make a lot of sense; moving an open-ended range is only possible if
the destination index is before the range, and in that case, the
client should be well aware how many songs there are.
Closes https://github.com/MusicPlayerDaemon/MPD/pull/1057
After commit 1afa33c3c7, an old bug was revealed:
SimpleDatabase::GetSong() constructs an ExportedSong instance by
moving the return value of Song::Export(), which causes the
LightSong::tag field to be dangling on the moved-from
ExportedSong::tag_buffer. This broke tags from CUE sheets.
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1070