use max(idelta, odelta) as clock reference

This commit is contained in:
Alexandre Ratchov 2012-10-05 19:35:31 +02:00
parent c257a68d18
commit 37c1d89c64
1 changed files with 61 additions and 68 deletions

View File

@ -348,7 +348,7 @@ sio_alsa_printpos(struct sio_alsa_hdl *hdl, int delta)
wdiff = wdiff - hdl->par.round; wdiff = wdiff - hdl->par.round;
} }
fprintf(stderr, DPRINTFN(2,
"clk: %+4lld %+4lld, wr %+4lld %+4lld rd: %+4lld %+4lld\n", "clk: %+4lld %+4lld, wr %+4lld %+4lld rd: %+4lld %+4lld\n",
cpos, cdiff, wpos, wdiff, rpos, rdiff); cpos, cdiff, wpos, wdiff, rpos, rdiff);
} }
@ -459,7 +459,7 @@ sio_alsa_xrun(struct sio_alsa_hdl *hdl)
{ {
int wdiff, cdiff, rdiff, offs; int wdiff, cdiff, rdiff, offs;
fprintf(stderr, "xrun: stop "); DPRINTF("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);
@ -470,7 +470,7 @@ sio_alsa_xrun(struct sio_alsa_hdl *hdl)
sio_onmove_cb(&hdl->sio, cdiff); sio_onmove_cb(&hdl->sio, cdiff);
} }
fprintf(stderr, "xrun: tick "); DPRINTF("xrun: tick ");
sio_alsa_printpos(hdl, 0); sio_alsa_printpos(hdl, 0);
if (hdl->sio.mode & SIO_PLAY) { if (hdl->sio.mode & SIO_PLAY) {
@ -492,10 +492,11 @@ sio_alsa_xrun(struct sio_alsa_hdl *hdl)
while (wdiff < offs) { while (wdiff < offs) {
wdiff += hdl->par.round; wdiff += hdl->par.round;
hdl->odelta -= hdl->par.round; hdl->odelta -= hdl->par.round;
hdl->idelta -= hdl->par.round;
hdl->cpos += hdl->par.round; hdl->cpos += hdl->par.round;
} }
} }
fprintf(stderr, "xrun: inserting silence: %d\n", wdiff); DPRINTF("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 - offs; hdl->idrop = wdiff - offs;
@ -505,11 +506,11 @@ sio_alsa_xrun(struct sio_alsa_hdl *hdl)
hdl->idelta -= hdl->par.round; hdl->idelta -= hdl->par.round;
hdl->cpos += hdl->par.round; hdl->cpos += hdl->par.round;
} }
fprintf(stderr, "xrun: dropping: %d\n", rdiff); DPRINTF("xrun: dropping: %d\n", rdiff);
hdl->idrop = rdiff; hdl->idrop = rdiff;
} }
fprintf(stderr, "xrun: osil = %d, idrop = %d\n", hdl->osil, hdl->idrop); DPRINTF("xrun: osil = %d, idrop = %d\n", hdl->osil, hdl->idrop);
fprintf(stderr, "xrun: corr "); DPRINTF("xrun: corr ");
sio_alsa_printpos(hdl, 0); sio_alsa_printpos(hdl, 0);
return 1; return 1;
} }
@ -969,7 +970,7 @@ sio_alsa_rdrop(struct sio_alsa_hdl *hdl)
hdl->rpos += n; hdl->rpos += n;
#endif #endif
hdl->idelta += n; hdl->idelta += n;
DPRINTF("sio_alsa_rdrop: dropped %ld/%ld frames\n", n, todo); DPRINTF("sio_alsa_rdrop: dropped %zu/%zu frames\n", n, todo);
} }
return 1; return 1;
} }
@ -1037,7 +1038,7 @@ sio_alsa_wsil(struct sio_alsa_hdl *hdl)
#endif #endif
hdl->odelta += n; 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 %zu/%zu frames\n", n, todo);
} }
return 1; return 1;
} }
@ -1056,12 +1057,12 @@ sio_alsa_write(struct sio_hdl *sh, const void *buf, size_t len)
* forever. Fix this by saving partial samples in a * forever. Fix this by saving partial samples in a
* temporary buffer. * temporary buffer.
*/ */
fprintf(stderr, "sio_alsa_write: wrong chunk size\n"); DPRINTF("sio_alsa_write: wrong chunk size\n");
hdl->sio.eof = 1; hdl->sio.eof = 1;
return 0; return 0;
} }
todo = len / hdl->obpf; todo = len / hdl->obpf;
DPRINTF("sio_alsa_write: len = %zd, todo = %zd\n", len, todo); DPRINTFN(2, "sio_alsa_write: len = %zd, todo = %zd\n", len, todo);
while ((n = snd_pcm_writei(hdl->opcm, buf, todo)) < 0) { while ((n = snd_pcm_writei(hdl->opcm, buf, todo)) < 0) {
if (n == -EINTR) if (n == -EINTR)
continue; continue;
@ -1073,7 +1074,7 @@ sio_alsa_write(struct sio_hdl *sh, const void *buf, size_t len)
} }
return 0; return 0;
} }
DPRINTF("wrote %zd\n", n); DPRINTFN(2, "sio_alsa_write: wrote %zd\n", n);
#ifdef DEBUG #ifdef DEBUG
hdl->wpos += n; hdl->wpos += n;
#endif #endif
@ -1133,12 +1134,11 @@ sio_alsa_pollfd(struct sio_hdl *sh, struct pollfd *pfd, int events)
hdl->infds = 0; hdl->infds = 0;
DPRINTF("sio_alsa_pollfd: events = %x, nfds = %d + %d\n", DPRINTF("sio_alsa_pollfd: events = %x, nfds = %d + %d\n",
events, hdl->onfds, hdl->infds); events, hdl->onfds, hdl->infds);
#if 0
for (i = 0; i < hdl->onfds + hdl->infds; i++) { for (i = 0; i < hdl->onfds + hdl->infds; i++) {
DPRINTF("sio_alsa_pollfd: pfds[%d].events = %x\n", DPRINTFN(3, "sio_alsa_pollfd: pfds[%d].events = %x\n",
i, pfd[i].events); i, pfd[i].events);
} }
#endif
return hdl->onfds + hdl->infds; return hdl->onfds + hdl->infds;
} }
@ -1150,18 +1150,17 @@ sio_alsa_revents(struct sio_hdl *sh, struct pollfd *pfd)
snd_pcm_state_t istate, ostate; snd_pcm_state_t istate, ostate;
int nfds; int nfds;
unsigned short revents, r; unsigned short revents, r;
int err; int delta, err;
#if 1
int i; int i;
for (i = 0; i < hdl->onfds + hdl->infds; i++) {
DPRINTF("sio_alsa_revents: pfds[%d].events = %x\n",
i, pfd[i].revents);
}
#endif
if (hdl->sio.eof) if (hdl->sio.eof)
return POLLHUP; return POLLHUP;
for (i = 0; i < hdl->onfds + hdl->infds; i++) {
DPRINTFN(3, "sio_alsa_revents: pfds[%d].events = %x\n",
i, pfd[i].revents);
}
revents = nfds = 0; revents = nfds = 0;
if ((hdl->events & POLLOUT) && (hdl->sio.mode & SIO_PLAY)) { if ((hdl->events & POLLOUT) && (hdl->sio.mode & SIO_PLAY)) {
ostate = snd_pcm_state(hdl->opcm); ostate = snd_pcm_state(hdl->opcm);
@ -1195,59 +1194,53 @@ sio_alsa_revents(struct sio_hdl *sh, struct pollfd *pfd)
revents |= r; revents |= r;
nfds += hdl->infds; nfds += hdl->infds;
} }
DPRINTF("sio_alsa_revents: revents = %x\n", revents); DPRINTFN(2, "sio_alsa_revents: revents = %x\n", revents);
if ((revents & POLLOUT) && (hdl->sio.mode & SIO_PLAY) && if (revents & (POLLIN | POLLOUT)) {
(ostate == SND_PCM_STATE_RUNNING || if ((hdl->sio.mode & SIO_PLAY) &&
ostate == SND_PCM_STATE_PREPARED)) { (ostate == SND_PCM_STATE_RUNNING ||
oavail = snd_pcm_avail_update(hdl->opcm); ostate == SND_PCM_STATE_PREPARED)) {
if (oavail < 0) { oavail = snd_pcm_avail_update(hdl->opcm);
if (oavail == -EPIPE) { if (oavail < 0) {
if (!sio_alsa_xrun(hdl)) if (oavail == -EPIPE) {
return POLLHUP; if (!sio_alsa_xrun(hdl))
return 0; return POLLHUP;
return 0;
}
DALSA("couldn't get play buffer pointer", oavail);
hdl->sio.eof = 1;
return POLLHUP;
} }
DALSA("couldn't get play buffer pointer", oavail); oused = hdl->par.bufsz - oavail;
hdl->sio.eof = 1; hdl->odelta += oused - hdl->oused;
return POLLHUP; hdl->oused = oused;
} }
oused = hdl->par.bufsz - oavail; if ((hdl->sio.mode & SIO_REC) &&
hdl->odelta += oused - hdl->oused; (istate == SND_PCM_STATE_RUNNING ||
hdl->oused = oused; istate == SND_PCM_STATE_PREPARED)) {
while (hdl->odelta > 0) { iused = snd_pcm_avail_update(hdl->ipcm);
#ifdef DEBUG if (iused < 0) {
hdl->cpos += hdl->odelta; if (iused == -EPIPE) {
if (sndio_debug) if (!sio_alsa_xrun(hdl))
sio_alsa_printpos(hdl, hdl->odelta); return POLLHUP;
#endif return 0;
sio_onmove_cb(&hdl->sio, hdl->odelta); }
hdl->odelta = 0; DALSA("couldn't get rec buffer pointer", iused);
} hdl->sio.eof = 1;
} return POLLHUP;
if ((revents & POLLIN) && !(hdl->sio.mode & SIO_PLAY) &&
(istate == SND_PCM_STATE_RUNNING ||
istate == SND_PCM_STATE_PREPARED)) {
iused = snd_pcm_avail_update(hdl->ipcm);
if (iused < 0) {
if (iused == -EPIPE) {
if (!sio_alsa_xrun(hdl))
return POLLHUP;
return 0;
} }
DALSA("couldn't get rec buffer pointer", iused); hdl->idelta += iused - hdl->iused;
hdl->sio.eof = 1; hdl->iused = iused;
return POLLHUP;
} }
//fprintf(stderr, "iused = %d -> %d, idelta = %d\n", hdl->iused, iused, hdl->idelta); delta = hdl->odelta > hdl->idelta ? hdl->odelta : hdl->idelta;
hdl->idelta += iused - hdl->iused; if (delta > 0) {
hdl->iused = iused;
if (hdl->idelta > 0) {
#ifdef DEBUG #ifdef DEBUG
hdl->cpos += hdl->idelta; hdl->cpos += delta;
if (sndio_debug) if (sndio_debug)
sio_alsa_printpos(hdl, hdl->odelta); sio_alsa_printpos(hdl, delta);
#endif #endif
sio_onmove_cb(&hdl->sio, hdl->idelta); sio_onmove_cb(&hdl->sio, delta);
hdl->idelta = 0; hdl->odelta -= delta;
hdl->idelta -= delta;
} }
} }
if ((hdl->sio.mode & SIO_PLAY) && !sio_alsa_wsil(hdl)) if ((hdl->sio.mode & SIO_PLAY) && !sio_alsa_wsil(hdl))