output/alsa: drain the whole `ring_buffer`, not just one period

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.
This commit is contained in:
Max Kellermann 2018-11-14 13:35:17 +01:00
parent 5d12f52873
commit 436ba3c96c
2 changed files with 5 additions and 5 deletions

1
NEWS
View File

@ -2,6 +2,7 @@ ver 0.21.3 (not yet released)
* output * output
- alsa: fix crash bug - alsa: fix crash bug
- alsa: fix stuttering at start of playback - alsa: fix stuttering at start of playback
- alsa: fix discarded samples at end of song
- alsa: clear error after reopening device - alsa: clear error after reopening device
* log: default to journal if MPD was started as systemd service * log: default to journal if MPD was started as systemd service

View File

@ -749,11 +749,10 @@ AlsaOutput::DrainInternal()
snd_strerror(-frames_written)); snd_strerror(-frames_written));
} }
if (!period_buffer.IsEmpty()) /* need to call CopyRingToPeriodBuffer() and
/* need to call WriteFromPeriodBuffer() again WriteFromPeriodBuffer() again in the next
in the next iteration, so don't finish the iteration, so don't finish the drain just yet */
drain just yet */ return period_buffer.IsEmpty();
return false;
} }
/* .. and finally drain the ALSA hardware buffer */ /* .. and finally drain the ALSA hardware buffer */