if (pcm->io.stream == SND_PCM_STREAM_CAPTURE)
size -= pcm->offset;
+ /* Prevent accidental overrun of the fake ringbuffer */
+ if (size >= pcm->buffer_attr.tlength)
+ size = pcm->buffer_attr.tlength-1;
+
if (size > pcm->last_size) {
pcm->ptr += size - pcm->last_size;
pcm->ptr %= pcm->buffer_attr.tlength;
snd_pcm_pulse_t *pcm = io->private_data;
const char *buf;
snd_pcm_sframes_t ret = 0;
+ size_t writebytes;
assert(pcm);
(char *) areas->addr + (areas->first +
areas->step * offset) / 8;
- ret = pa_stream_write(pcm->stream, buf, size * pcm->frame_size, NULL, 0, 0);
+ writebytes = size * pcm->frame_size;
+ ret = pa_stream_write(pcm->stream, buf, writebytes, NULL, 0, 0);
if (ret < 0) {
ret = -EIO;
goto finish;
}
/* Make sure the buffer pointer is in sync */
+ pcm->last_size -= writebytes;
ret = update_ptr(pcm);
if (ret < 0)
goto finish;
dst_buf = (char *) dst_buf + frag_length;
remain_size -= frag_length;
+ pcm->last_size -= frag_length;
}
/* Make sure the buffer pointer is in sync */
pcm->offset = 0;
pcm->underrun = 0;
+ /* Reset fake ringbuffer */
+ pcm->last_size = 0;
+ pcm->ptr = 0;
+ update_ptr(pcm);
+
finish:
pa_threaded_mainloop_unlock(pcm->p->mainloop);