- 28 Jun, 2019 8 commits
-
-
Max Kellermann authored
MPD used to do that when this code lived in the player thread, but it was removed by commit 98a7c62d; and the replacement code in the ALSA output plugin didn't have it.
-
Max Kellermann authored
Without this timer, DispatchSockets() may disable the MultiSocketMonitor and if Play() doesn't get called soon, it never gets a chance to generate silence. However if Play() gets called, generating silence isn't necessary anymore... Resulting from this misdesign (added by commit ccafe3f3 in 0.21.3), the silence generator didn't work reliably.
-
Max Kellermann authored
In DispatchSockets(), when there was not enough data, but enough for current playback, the method would disable the "active" flag so the next Play() call would re-enable the MultiSocketMonitor. This was an abuse of the flag which could result in a crash in Cancel(), because that method asserts that the period_buffer is empty, which it may be not. The solution is to add anther flag called "waiting" which shares some behavior with the old flag.
-
Max Kellermann authored
-
Max Kellermann authored
-
Max Kellermann authored
-
Max Kellermann authored
Draining isn't finished just because the period_buffer has run empty. It is only finished after snd_pcm_drain() has succeeded.
-
Max Kellermann authored
Apparently, if snd_pcm_drain() returns EAGAIN, it does not actually want to be called again; the next call will snd_pcm_drain() will also return EAGAIN, forever, even though the PCM state has meanwhile switched to SND_PCM_STATE_SETUP. This causes a busy loop; to fix this, we should always check snd_pcm_state() to see if draining is really required.
-
- 16 Nov, 2018 1 commit
-
-
Max Kellermann authored
Works around a problem where MPD goes into a busy loop because snd_pcm_drain() always returns `-EAGAIN` without making any progress (fixes #425). This problem was triggered by snd_pcm_drain() after snd_pcm_cancel() and snd_pcm_prepare(), but without submitting any data with snd_pcm_writei(). I believe this is a kernel bug: in non-blocking mode, the kernel's snd_pcm_drain() function returns early. In this mode, it only checks whether snd_pcm_drain_done() has been called already, but snd_pcm_drain_done() is never called if no data was submitted. In blocking mode, the following `for` loop detects this condition, so snd_pcm_drain_done() is not necessary, but without this extra check, we get `-EAGAIN` forever.
-
- 14 Nov, 2018 12 commits
-
-
Max Kellermann authored
This fixes a problem which caused a failure with snd_pcm_writei() because snd_pcm_drain() had already been called in the previous iteration. This commit makes sure that snd_pcm_drain() is only called after the final snd_pcm_writei() call. This fixes discarded samples at the end of playback.
-
Max Kellermann authored
When a playback error has occurred, MPD would never recover until one restarts MPD.
-
Max Kellermann authored
CancelInternal() doesn't need to be protected because it is called synchronously from Cancel().
-
Max Kellermann authored
Fixes a theoretical race condition which could occur in Drain() (but was extremely unlikely).
-
Max Kellermann authored
If our `ring_buffer` is smaller than the ALSA-PCM buffer (if the latter has more than the 4 periods we allocate), it can happen that the start threshold is crossed and ALSA switches to `SND_PCM_STATE_RUNNING`, but the `ring_buffer` is empty. In this case, MPDD will generate silence, even though the ALSA-PCM buffer has enough data. This causes stuttering (#420). This commit amends an older workaround for a similar problem (commit e08598e7) by adding a snd_pcm_avail() check, and only generate silence if there is less than one period of data in the ALSA-PCM buffer. Fixes #420
-
Max Kellermann authored
The method Cancel() assumes that the `period_buffer` must be empty when `active==false`, but that is not the case when Play() fails. Of course the assertion in Cancel() is not 100% correct, but I decided to rather fix this in LockCaughtError() because the `period_buffer` should only be accessed from within the RTIO thread, and this is the only code path where `active` can be set to `false` with a non-empty `period_buffer`. Fixes #423
-
Max Kellermann authored
This implements real error handling, and avoids calling CancelInternal() from this code path.
-
Max Kellermann authored
alsa-lib doesn't set errno, it returns errors as negative integers.
-
Max Kellermann authored
-
Max Kellermann authored
-
Max Kellermann authored
This check was added 9 years ago in commit 4dc25d39 to work around a dmix bug which I assume has been fixed long ago. Removing this fixes another corner case: if draining is requested before the start threshold is reached, the PCM is still in SND_PCM_STATE_PREPARED but not yet SND_PCM_STATE_RUNNING, which means the submitted data will never be played. This corner case is realistic when playing songs shorter than the ALSA buffer (if the buffer is very large).
-
Max Kellermann authored
This fixes a corner case which has probably never occurred and probably never will: if Cancel() is called, and then Play() followed by Drain(), the plugin should really play that data. However currently, this never happens, because snd_pcm_prepare() is never called.
-
- 11 Nov, 2018 2 commits
-
-
Max Kellermann authored
This call was missing, causing very high CPU usage when the ALSA output plugin was used with dmix. Closes #391
-
Max Kellermann authored
-
- 31 Oct, 2018 1 commit
-
-
Max Kellermann authored
-
- 16 Jul, 2018 1 commit
-
-
Max Kellermann authored
This method was added in Boost 1.58.
-
- 03 May, 2018 1 commit
-
-
Max Kellermann authored
-
- 26 Apr, 2018 9 commits
-
-
Max Kellermann authored
See code comment. Closes #260
-
Max Kellermann authored
-
Max Kellermann authored
Don't reactivate the PCM device immediately after Cancel() is finished; if Cancel() gets called this may mean that new data may take a while to produce, or no data at all will be produced because the current song is being stopped. Once new data is available, Play() will automatically reactivate the PCM. This fixes underruns when switching songs manually (closes #264).
-
Max Kellermann authored
Use the "active" flag in PrepareSockets() instead of LockHasError().
-
Max Kellermann authored
-
Max Kellermann authored
Prepare to make the "active" attribute thread-safe.
-
Max Kellermann authored
-
Max Kellermann authored
-
Max Kellermann authored
-
- 10 Apr, 2018 1 commit
-
-
Max Kellermann authored
-
- 02 Jan, 2018 1 commit
-
-
Max Kellermann authored
Adds missing checks to several plugins.
-
- 19 Dec, 2017 2 commits
-
-
Max Kellermann authored
-
Max Kellermann authored
-
- 14 Nov, 2017 1 commit
-
-
Max Kellermann authored
Avoid another potential deadlock: if no file descriptors are registered, our non-blocking ALSA code cannot ever work.
-