diff --git a/src/pcm/pcm_ioplug.c b/src/pcm/pcm_ioplug.c index a437ca326..33a6aa78f 100644 --- a/src/pcm/pcm_ioplug.c +++ b/src/pcm/pcm_ioplug.c @@ -727,7 +727,12 @@ static snd_pcm_sframes_t snd_pcm_ioplug_avail_update(snd_pcm_t *pcm) const snd_pcm_channel_area_t *areas; snd_pcm_uframes_t offset, size = UINT_MAX; snd_pcm_sframes_t result; + /* avail may be > buffer_size and thus must be manually limited if used for 2nd transfer() call + w/o another mmap_commit() plus mmap_begin() issued after 1st transfer() */ + snd_pcm_uframes_t avail_part = avail % pcm->buffer_size; + if (avail && !avail_part) /*avail = (n*buffer_size) results in buffer_size */ + avail_part = pcm->buffer_size; __snd_pcm_mmap_begin(pcm, &areas, &offset, &size); result = io->data->callback->transfer(io->data, areas, offset, size); if (result < 0) @@ -737,9 +742,9 @@ static snd_pcm_sframes_t snd_pcm_ioplug_avail_update(snd_pcm_t *pcm) contiguous area at the end of the mmap we must transfer the remaining data to the beginning of the mmap. */ - if (size < avail) { + if (size < avail_part) { result = io->data->callback->transfer(io->data, areas, - 0, avail - size); + 0, avail_part - size); if (result < 0) return result; }