Open fwsmit opened 3 years ago
I am experiencing the same. I've played with available configuration options and found that reducing the buffer_time
inside audio_output
config block alleviates the problem for me. I am using ALSA output, so reducing it from the default 500000
μs to e.g. 25000
makes the skipped time almost imperceptible:
audio_output {
type "alsa"
name "ALSA output"
buffer_time "25000"
}
However, the documentation states:
Don’t change unless you know what you’re doing.
and since I don't really know what I am doing I am not sure if it is a good solution. According to this blog post, reducing it increases MPD's CPU usage and that seems to be true. Not sure what other potentially negative effects changing it might have.
I have also noticed this issue, using both the pulse and pipewire outputs.
I am also experiencing this. Is there a known solution?
Not really. There is a workaround mentioned above, but I guess that buffer is there for a reason, so I don't want to mess with it. I've tried looking if I can fix it in mpd, but haven't found where to begin
Out of interest, what audio hardware do you have? And how is it connected? And which audio daemon do you use (pulse, pipewire, etc)
I've had this issue with both pulseuadio and pipewire. I'm using the internal intel audio of my laptop:
Audio device [0403]: Intel Corporation Cannon Lake PCH cAVS [8086:a348] (rev 10) (prog-if 80) Subsystem: Hewlett-Packard Company Device [103c:8427]
, but it's also reproducible with a headset connected to bluetooth or on other hardware.
My full audio info can be found here.
I think the problem is that audio outputs don't have an interface for unpausing, and the unpausing logic actually re-opens the outputs, thus discarding buffers.
I think we need a virtual AudioOutput::Unpause
that returns false
, an overridden PulseOutput::Unpause
that just does the opposite of PulseOutput::Pause
(similarly for other outputs that support pausing), and then the unpausing logic should do something like if (!output.Unpause()) output.Open()
for all outputs. I can try implementing this but I'm not too sure about how to handle the asynchronous stuff. @MaxKellermann thoughts?
I didn't think of this approach. I'm not familiar with the code, but from the linked code, I don't really see if it should work. I'm willing to test the code though, if you have a proof of concept.
I vaguely remember discussing this a long time ago in 2016 on the old mantis system (https://bugs.musicpd.org/view.php?id=4528 dead link now unfortunately) and it is ultimately what made me switch away from the mpd ecosystem. I am resurrecting what I can extract from my email archives here.
A NOTE has been added to this issue.
======================================================================
https://bugs.musicpd.org/view.php?id=4528
======================================================================
Reported By: incertia
Assigned To:
======================================================================
Project: MPD
Issue ID: 4528
Category: MPD
Reproducibility: always
Severity: minor
Priority: normal
Status: new
======================================================================
Date Submitted: 2016-05-16 19:32 UTC
Last Modified: 2016-05-17 20:11 UTC
======================================================================
Summary: pause command skips minor amounts of audio
Description:
when pausing/unpausing mpd, mpd will pause to what seems like the nearest 0.25
second rather stopping at the current time slice.
Steps to Reproduce:
pause/unpause repeatedly in rapid fashion
demo: https://my.mixtape.moe/cgqrlv.mp4
======================================================================
----------------------------------------------------------------------
(0009939) cirrus (administrator) - 2016-05-17 15:31
https://bugs.musicpd.org/view.php?id=4528#c9939
----------------------------------------------------------------------
This is an unfortunate side effect of MPD clearing the ring buffer on pause.
----------------------------------------------------------------------
(0009941) cirrus (administrator) - 2016-05-17 18:29
https://bugs.musicpd.org/view.php?id=4528#c9941
----------------------------------------------------------------------
Audio playback isn't that simple. You can't just stop sending data. If you do,
your computer will keep on playing for a few seconds, until all buffers have run
empty. Users however expect MPD to pause playback instantly after pressing
"pause", which involves flushing all those buffers.
----------------------------------------------------------------------
(0009943) incertia (reporter) - 2016-05-17 19:14
https://bugs.musicpd.org/view.php?id=4528#c9943
----------------------------------------------------------------------
Can't we just save which time slice we currently are on when we initiate a pause
command and start reloading the audio buffer from that slice on an unpause
operation?
e.g. for PulseAudio, we should be able to use pa_stream_cork(true/false) to have
pulse halt audio immediately and retain the information in the buffer (unless my
understanding from
https://freedesktop.org/software/pulseaudio/doxygen/stream_8h.html#a14e698233ac2d246646651955ab0ec7b
is incorrect).
----------------------------------------------------------------------
(0009945) cirrus (administrator) - 2016-05-17 19:11
https://bugs.musicpd.org/view.php?id=4528#c9945
----------------------------------------------------------------------
Of course you can do that. But I wouldn't, because this means massive amounts of
overhead, for a lousy result. There's a better way to do it (keep samples in the
buffer until it's really been played completely by all outputs, not just put in
their ring buffers), but it's complicated to implement. Would take one quite a
few hours to implement, and this isn't the most urgent request.
----------------------------------------------------------------------
(0009946) VAMP (reporter) - 2016-05-17 19:17
https://bugs.musicpd.org/view.php?id=4528#c9946
----------------------------------------------------------------------
I think this problem also applies to "clicks while rewinding tracks in DSD DoP
mode "
----------------------------------------------------------------------
(0009947) cirrus (administrator) - 2016-05-17 19:18
https://bugs.musicpd.org/view.php?id=4528#c9947
----------------------------------------------------------------------
No, it doesn't.
----------------------------------------------------------------------
(0009948) incertia (reporter) - 2016-05-17 19:25
https://bugs.musicpd.org/view.php?id=4528#c9948
----------------------------------------------------------------------
Ok I just tried what I mentioned with pa_stream_cork and while it does offer
better pausing, it produces unwanted static for a short period of time. I'll see
if I can hack together a solution and upload a patch during my free time.
----------------------------------------------------------------------
(0009950) incertia (reporter) - 2016-05-17 20:08
https://bugs.musicpd.org/view.php?id=4528#c9950
----------------------------------------------------------------------
Continuing with https://bugs.musicpd.org/view.php?id=4528#c9948, we actually
don't need to cork the stream in PulseOutput::Pause(). The stream ends up with
no data due to PulseOutput::Cancel(), so
<pre>
if (!pa_stream_is_corked(stream) && !StreamPause(true, error)) {
pa_threaded_mainloop_unlock(mainloop);
LogError(error);
return false;
}
</pre>
ends up not really doing anything (behavior is the same when this bit is
commented out). In fact, with pulse, AudioOutput::Pause() can behave like
<pre>
inline void
AudioOutput::Pause()
{
mutex.unlock();
ao_plugin_cancel(this);
mutex.lock();
pause = true;
CommandFinished();
do {
if (!WaitForDelay())
break;
mutex.unlock();
// bool success = ao_plugin_pause(this);
mutex.lock();
// if (!success) {
// Close(false);
// break;
// }
} while (command == Command::NONE);
pause = false;
}
</pre>
and still achieve the desired result. However, removing the mutex unlock/lock
sequence causes clients to timeout for some unknown reason.
----------------------------------------------------------------------
(0009951) cirrus (administrator) - 2016-05-17 20:11
https://bugs.musicpd.org/view.php?id=4528#c9951
----------------------------------------------------------------------
That's because you just created a busy loop with a mutex held. When you leave
the unlock/lock in, it only occurs to be responsive randomly. This change is
bad.
Issue History
Date Modified Username Field Change
======================================================================
2016-05-16 19:32 incertia New Issue
2016-05-16 19:33 incertia Tag Attached: mpd
2016-05-16 19:33 incertia Tag Attached: commands
2016-05-17 15:31 cirrus Note Added: 0009939
2016-05-17 17:52 incertia Note Added: 0009940
2016-05-17 18:03 incertia Note Edited: 0009940
2016-05-17 18:28 incertia Note Deleted: 0009940
2016-05-17 18:29 cirrus Note Added: 0009941
2016-05-17 19:07 incertia Note Added: 0009943
2016-05-17 19:11 incertia Note Edited: 0009943
2016-05-17 19:11 cirrus Note Added: 0009945
2016-05-17 19:14 incertia Note Edited: 0009943
2016-05-17 19:14 incertia Note Edited: 0009943
2016-05-17 19:17 VAMP Note Added: 0009946
2016-05-17 19:18 cirrus Note Added: 0009947
2016-05-17 19:25 incertia Note Added: 0009948
2016-05-17 20:08 incertia Note Added: 0009950
2016-05-17 20:11 cirrus Note Added: 0009951
======================================================================
In particular, I still have no idea how to fix this issue and it also seems like it is a very low priority issue (despite offering not very good UX) so I wish anyone else wanting to take up the torch the best of luck.
2023 And that's still a problem. Will it ever be fixed?
If it's important enough that it's worth your time, go ahead and fix it. If it's not important enough for your time, it's not important enough.
But is that so hard to fix? I mean, if there is a problem it should be fixed. I wanted to know whether there's any progress on this
If you believe it should be fixed, go ahead and fix it. Put your time where your mouth is. If you're not willing to take the time to help fix it, please stop spamming here.
But is that so hard to fix? I mean, if there is a problem it should be fixed. I wanted to know whether there's any progress on this
Looking at the list of open issues, it's not very small. And I assume the maintainers, like most open source developers, work on this project in their free time. They have to prioritize stuff and this is a relatively minor problem when looking at the problem description. If this issue is important to you, you should really consider fixing it yourself. Developers are only humans with limited capacity to work on free and open source projects...
And I assume the maintainers, like most open source developers, work on this project in their free time.
I know. I just wanted to ask. If there's none, then okay. You know better what to do with the project than me
Bug report
Describe the bug
Why I toggle mpd playback twice in a short time, a second of the song is skipped. This can be most easily reproduced when running the following commands when mpd is paused:`
Expected Behavior
No / very little time is skipped
Actual Behavior
1 second is skipped
Version
Log
Command output
mpd output