Merge tag 'v0.18.13'
This commit is contained in:
@@ -825,6 +825,7 @@ alsa_play(AudioOutput *ao, const void *chunk, size_t size,
|
||||
{
|
||||
AlsaOutput *ad = (AlsaOutput *)ao;
|
||||
|
||||
assert(size > 0);
|
||||
assert(size % ad->in_frame_size == 0);
|
||||
|
||||
if (ad->must_prepare) {
|
||||
@@ -838,12 +839,22 @@ alsa_play(AudioOutput *ao, const void *chunk, size_t size,
|
||||
}
|
||||
|
||||
const auto e = ad->pcm_export->Export({chunk, size});
|
||||
if (e.size == 0)
|
||||
/* the DoP (DSD over PCM) filter converts two frames
|
||||
at a time and ignores the last odd frame; if there
|
||||
was only one frame (e.g. the last frame in the
|
||||
file), the result is empty; to avoid an endless
|
||||
loop, bail out here, and pretend the one frame has
|
||||
been played */
|
||||
return size;
|
||||
|
||||
chunk = e.data;
|
||||
size = e.size;
|
||||
|
||||
assert(size % ad->out_frame_size == 0);
|
||||
|
||||
size /= ad->out_frame_size;
|
||||
assert(size > 0);
|
||||
|
||||
while (true) {
|
||||
snd_pcm_sframes_t ret = ad->writei(ad->pcm, chunk, size);
|
||||
|
@@ -724,6 +724,8 @@ oss_output_play(AudioOutput *ao, const void *chunk, size_t size,
|
||||
OssOutput *od = (OssOutput *)ao;
|
||||
ssize_t ret;
|
||||
|
||||
assert(size > 0);
|
||||
|
||||
/* reopen the device since it was closed by dropBufferedAudio */
|
||||
if (od->fd < 0 && !oss_reopen(od, error))
|
||||
return 0;
|
||||
@@ -734,6 +736,8 @@ oss_output_play(AudioOutput *ao, const void *chunk, size_t size,
|
||||
size = e.size;
|
||||
#endif
|
||||
|
||||
assert(size > 0);
|
||||
|
||||
while (true) {
|
||||
ret = write(od->fd, chunk, size);
|
||||
if (ret > 0) {
|
||||
|
@@ -251,6 +251,10 @@ public:
|
||||
|
||||
void PlayPrevious(PlayerControl &pc);
|
||||
|
||||
PlaylistResult SeekSongOrder(PlayerControl &pc,
|
||||
unsigned song_order,
|
||||
SongTime seek_time);
|
||||
|
||||
PlaylistResult SeekSongPosition(PlayerControl &pc,
|
||||
unsigned song_position,
|
||||
SongTime seek_time);
|
||||
|
@@ -190,18 +190,12 @@ playlist::PlayPrevious(PlayerControl &pc)
|
||||
}
|
||||
|
||||
PlaylistResult
|
||||
playlist::SeekSongPosition(PlayerControl &pc,
|
||||
unsigned song, SongTime seek_time)
|
||||
playlist::SeekSongOrder(PlayerControl &pc, unsigned i, SongTime seek_time)
|
||||
{
|
||||
if (!queue.IsValidPosition(song))
|
||||
return PlaylistResult::BAD_RANGE;
|
||||
assert(queue.IsValidOrder(i));
|
||||
|
||||
const DetachedSong *queued_song = GetQueuedSong();
|
||||
|
||||
unsigned i = queue.random
|
||||
? queue.PositionToOrder(song)
|
||||
: song;
|
||||
|
||||
pc.ClearError();
|
||||
stop_on_error = true;
|
||||
error_count = 0;
|
||||
@@ -228,6 +222,20 @@ playlist::SeekSongPosition(PlayerControl &pc,
|
||||
return PlaylistResult::SUCCESS;
|
||||
}
|
||||
|
||||
PlaylistResult
|
||||
playlist::SeekSongPosition(PlayerControl &pc, unsigned song,
|
||||
SongTime seek_time)
|
||||
{
|
||||
if (!queue.IsValidPosition(song))
|
||||
return PlaylistResult::BAD_RANGE;
|
||||
|
||||
unsigned i = queue.random
|
||||
? queue.PositionToOrder(song)
|
||||
: song;
|
||||
|
||||
return SeekSongOrder(pc, i, seek_time);
|
||||
}
|
||||
|
||||
PlaylistResult
|
||||
playlist::SeekSongId(PlayerControl &pc, unsigned id, SongTime seek_time)
|
||||
{
|
||||
@@ -257,5 +265,8 @@ playlist::SeekCurrent(PlayerControl &pc,
|
||||
seek_time = SignedSongTime::zero();
|
||||
}
|
||||
|
||||
return SeekSongPosition(pc, current, SongTime(seek_time));
|
||||
if (seek_time.IsNegative())
|
||||
seek_time = SignedSongTime::zero();
|
||||
|
||||
return SeekSongOrder(pc, current, SongTime(seek_time));
|
||||
}
|
||||
|
Reference in New Issue
Block a user