mirror of https://github.com/ericonr/sndio.git
handle rec xruns as well
This commit is contained in:
parent
8961afb69e
commit
2630880acc
|
@ -456,32 +456,17 @@ sio_alsa_stop(struct sio_hdl *sh)
|
||||||
static int
|
static int
|
||||||
sio_alsa_xrun(struct sio_alsa_hdl *hdl)
|
sio_alsa_xrun(struct sio_alsa_hdl *hdl)
|
||||||
{
|
{
|
||||||
long long _wpos, _rpos, _cpos;
|
int wdiff, cdiff, rdiff, offs;
|
||||||
int wdiff, rdiff, cdiff;
|
|
||||||
|
|
||||||
fprintf(stderr, "xrun: idelta = %d, odelta = %d\n", hdl->idelta, hdl->odelta);
|
|
||||||
fprintf(stderr, "xrun: stop ");
|
fprintf(stderr, "xrun: stop ");
|
||||||
sio_alsa_printpos(hdl, 0);
|
sio_alsa_printpos(hdl, 0);
|
||||||
|
|
||||||
cdiff = hdl->par.round - (hdl->cpos % hdl->par.round);
|
cdiff = hdl->par.round - (hdl->cpos % hdl->par.round);
|
||||||
if (cdiff == hdl->par.round)
|
if (cdiff == hdl->par.round)
|
||||||
cdiff = 0;
|
cdiff = 0;
|
||||||
if (hdl->sio.mode & SIO_PLAY) {
|
if (cdiff > 0) {
|
||||||
hdl->odelta += cdiff;
|
hdl->cpos += cdiff;
|
||||||
if (hdl->odelta) {
|
sio_onmove_cb(&hdl->sio, cdiff);
|
||||||
fprintf(stderr, "xrun: advancing by %d\n", hdl->odelta);
|
|
||||||
hdl->cpos += hdl->odelta;
|
|
||||||
sio_onmove_cb(&hdl->sio, hdl->odelta);
|
|
||||||
hdl->odelta = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
hdl->idelta += cdiff;
|
|
||||||
if (hdl->idelta) {
|
|
||||||
fprintf(stderr, "xrun: advancing by %d\n", hdl->idelta);
|
|
||||||
hdl->cpos += hdl->idelta;
|
|
||||||
sio_onmove_cb(&hdl->sio, hdl->idelta);
|
|
||||||
hdl->idelta = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "xrun: tick ");
|
fprintf(stderr, "xrun: tick ");
|
||||||
|
@ -489,13 +474,12 @@ sio_alsa_xrun(struct sio_alsa_hdl *hdl)
|
||||||
|
|
||||||
if (hdl->sio.mode & SIO_PLAY) {
|
if (hdl->sio.mode & SIO_PLAY) {
|
||||||
wdiff = hdl->wpos - hdl->cpos;
|
wdiff = hdl->wpos - hdl->cpos;
|
||||||
|
if (hdl->sio.mode & SIO_REC)
|
||||||
|
offs = hdl->wpos - hdl->rpos;
|
||||||
} else {
|
} else {
|
||||||
/* XXX */
|
rdiff = hdl->par.bufsz - (hdl->cpos - hdl->rpos);
|
||||||
}
|
}
|
||||||
|
|
||||||
_wpos = hdl->wpos;
|
|
||||||
_rpos = hdl->rpos;
|
|
||||||
_cpos = hdl->cpos;
|
|
||||||
if (!sio_alsa_stop(&hdl->sio))
|
if (!sio_alsa_stop(&hdl->sio))
|
||||||
return 0;
|
return 0;
|
||||||
if (!sio_alsa_start(&hdl->sio))
|
if (!sio_alsa_start(&hdl->sio))
|
||||||
|
@ -503,16 +487,25 @@ sio_alsa_xrun(struct sio_alsa_hdl *hdl)
|
||||||
hdl->running = 1;
|
hdl->running = 1;
|
||||||
|
|
||||||
if (hdl->sio.mode & SIO_PLAY) {
|
if (hdl->sio.mode & SIO_PLAY) {
|
||||||
|
if (hdl->sio.mode & SIO_REC) {
|
||||||
|
while (wdiff < offs) {
|
||||||
|
wdiff += hdl->par.round;
|
||||||
|
hdl->odelta -= hdl->par.round;
|
||||||
|
hdl->cpos += hdl->par.round;
|
||||||
|
}
|
||||||
|
}
|
||||||
fprintf(stderr, "xrun: inserting silence: %d\n", wdiff);
|
fprintf(stderr, "xrun: inserting silence: %d\n", wdiff);
|
||||||
hdl->osil = wdiff;
|
hdl->osil = wdiff;
|
||||||
if (hdl->sio.mode & SIO_REC) {
|
if (hdl->sio.mode & SIO_REC)
|
||||||
hdl->idrop = wdiff;
|
hdl->idrop = wdiff - offs;
|
||||||
hdl->osil += _wpos - _rpos;
|
|
||||||
/* XXX */
|
|
||||||
}
|
|
||||||
hdl->cpos -= hdl->odelta;
|
|
||||||
} else {
|
} else {
|
||||||
/* XXX */
|
while (rdiff > (int)hdl->par.bufsz) {
|
||||||
|
rdiff -= hdl->par.round;
|
||||||
|
hdl->idelta -= hdl->par.round;
|
||||||
|
hdl->cpos += hdl->par.round;
|
||||||
|
}
|
||||||
|
fprintf(stderr, "xrun: dropping: %d\n", rdiff);
|
||||||
|
hdl->idrop = rdiff;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "xrun: osil = %d, idrop = %d\n", hdl->osil, hdl->idrop);
|
fprintf(stderr, "xrun: osil = %d, idrop = %d\n", hdl->osil, hdl->idrop);
|
||||||
fprintf(stderr, "xrun: corr ");
|
fprintf(stderr, "xrun: corr ");
|
||||||
|
@ -960,6 +953,7 @@ sio_alsa_rdrop(struct sio_alsa_hdl *hdl)
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
hdl->rpos += n;
|
hdl->rpos += n;
|
||||||
#endif
|
#endif
|
||||||
|
hdl->idelta += n;
|
||||||
DPRINTF("sio_alsa_rdrop: dropped %ld/%ld frames\n", n, todo);
|
DPRINTF("sio_alsa_rdrop: dropped %ld/%ld frames\n", n, todo);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1026,6 +1020,7 @@ sio_alsa_wsil(struct sio_alsa_hdl *hdl)
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
hdl->wpos += n;
|
hdl->wpos += n;
|
||||||
#endif
|
#endif
|
||||||
|
hdl->odelta += n;
|
||||||
hdl->osil -= n;
|
hdl->osil -= n;
|
||||||
DPRINTF("sio_alsa_wsil: inserted %ld/%ld frames\n", n, todo);
|
DPRINTF("sio_alsa_wsil: inserted %ld/%ld frames\n", n, todo);
|
||||||
}
|
}
|
||||||
|
@ -1171,9 +1166,9 @@ sio_alsa_revents(struct sio_hdl *sh, struct pollfd *pfd)
|
||||||
if (hdl->sio.mode & SIO_REC) {
|
if (hdl->sio.mode & SIO_REC) {
|
||||||
istate = snd_pcm_state(hdl->ipcm);
|
istate = snd_pcm_state(hdl->ipcm);
|
||||||
if (istate == SND_PCM_STATE_XRUN) {
|
if (istate == SND_PCM_STATE_XRUN) {
|
||||||
fprintf(stderr, "sio_alsa_revents: record xrun\n");
|
if (!sio_alsa_xrun(hdl))
|
||||||
hdl->sio.eof = 1;
|
return POLLHUP;
|
||||||
return POLLHUP;
|
return 0;
|
||||||
}
|
}
|
||||||
err = snd_pcm_poll_descriptors_revents(hdl->ipcm, pfd + nfds, hdl->infds, &r);
|
err = snd_pcm_poll_descriptors_revents(hdl->ipcm, pfd + nfds, hdl->infds, &r);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
|
|
Loading…
Reference in New Issue