fixes for the sndio backend:
* deal with sio_{read,write} possibly moving less data than requested * check for out-of-sync conditions and restart if they occur makes running jackd over aucat much more reliable
This commit is contained in:
parent
0fda60bf3a
commit
7f381452e1
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: Makefile,v 1.8 2009/02/04 00:02:16 merdely Exp $
|
||||
# $OpenBSD: Makefile,v 1.9 2009/03/13 23:06:14 jakemsr Exp $
|
||||
|
||||
SHARED_ONLY = Yes
|
||||
|
||||
@ -6,7 +6,7 @@ COMMENT = low latency sound server
|
||||
|
||||
V = 0.116.1
|
||||
DISTNAME = jack-audio-connection-kit-${V}
|
||||
PKGNAME = jack-${V}p1
|
||||
PKGNAME = jack-${V}p2
|
||||
|
||||
SHARED_LIBS += jack 0.0 # 0.28
|
||||
SHARED_LIBS += jackserver 0.0 # 0.28
|
||||
|
@ -152,7 +152,7 @@ set_period_size (sndio_driver_t *driver, jack_nframes_t new_period_size)
|
||||
static void
|
||||
sndio_driver_write_silence (sndio_driver_t *driver, jack_nframes_t nframes)
|
||||
{
|
||||
size_t localsize, io_res;
|
||||
size_t localsize, io_res, nbytes, offset;
|
||||
void *localbuf;
|
||||
|
||||
localsize = nframes * driver->sample_bytes * driver->playback_channels;
|
||||
@ -164,14 +164,21 @@ sndio_driver_write_silence (sndio_driver_t *driver, jack_nframes_t nframes)
|
||||
return;
|
||||
}
|
||||
|
||||
offset = 0;
|
||||
bzero(localbuf, localsize);
|
||||
io_res = sio_write(driver->hdl, localbuf, localsize);
|
||||
if (io_res < localsize)
|
||||
nbytes = localsize;
|
||||
while (nbytes > 0)
|
||||
{
|
||||
io_res = sio_write(driver->hdl, localbuf, nbytes);
|
||||
if (io_res == 0)
|
||||
{
|
||||
jack_error("sndio_driver: sio_write() failed: "
|
||||
"count=%d/%d: %s@%i", io_res, localsize,
|
||||
__FILE__, __LINE__);
|
||||
}
|
||||
offset += io_res;
|
||||
nbytes -= io_res;
|
||||
}
|
||||
driver->playpos += nframes;
|
||||
free(localbuf);
|
||||
}
|
||||
@ -180,7 +187,7 @@ sndio_driver_write_silence (sndio_driver_t *driver, jack_nframes_t nframes)
|
||||
static void
|
||||
sndio_driver_read_silence (sndio_driver_t *driver, jack_nframes_t nframes)
|
||||
{
|
||||
size_t localsize, io_res;
|
||||
size_t localsize, io_res, nbytes, offset;
|
||||
void *localbuf;
|
||||
|
||||
localsize = nframes * driver->sample_bytes * driver->capture_channels;
|
||||
@ -192,13 +199,19 @@ sndio_driver_read_silence (sndio_driver_t *driver, jack_nframes_t nframes)
|
||||
return;
|
||||
}
|
||||
|
||||
offset = 0;
|
||||
bzero(localbuf, localsize);
|
||||
io_res = sio_read(driver->hdl, localbuf, localsize);
|
||||
if (io_res < localsize)
|
||||
{
|
||||
nbytes = localsize;
|
||||
while (nbytes > 0) {
|
||||
io_res = sio_read(driver->hdl, localbuf + offset, nbytes);
|
||||
if (io_res == 0) {
|
||||
jack_error("sndio_driver: sio_read() failed: "
|
||||
"count=%d/%d: %s@%i", io_res, localsize,
|
||||
"count=%d/%d: %s@%i", io_res, nbytes,
|
||||
__FILE__, __LINE__);
|
||||
break;
|
||||
}
|
||||
offset +=- io_res;
|
||||
nbytes -= io_res;
|
||||
}
|
||||
driver->cappos += nframes;
|
||||
free(localbuf);
|
||||
@ -215,8 +228,9 @@ sndio_driver_start (sndio_driver_t *driver)
|
||||
}
|
||||
|
||||
/* prime playback buffers */
|
||||
sndio_driver_write_silence(driver,
|
||||
driver->buffer_fill);
|
||||
if (driver->playback_channels > 0) {
|
||||
sndio_driver_write_silence(driver, driver->buffer_fill);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -255,7 +269,6 @@ sndio_driver_set_parameters (sndio_driver_t *driver)
|
||||
par.rate = driver->sample_rate;
|
||||
par.appbufsz = driver->period_size * driver->nperiods;
|
||||
par.round = driver->period_size;
|
||||
// par.xrun = SIO_SYNC;
|
||||
|
||||
if (!sio_setpar(driver->hdl, &par))
|
||||
{
|
||||
@ -368,13 +381,14 @@ sndio_driver_wait (sndio_driver_t *driver, int *status, float *iodelay)
|
||||
jack_time_t poll_enter;
|
||||
jack_time_t poll_ret;
|
||||
int need_capture, need_playback;
|
||||
int cap_avail, play_avail;
|
||||
long long cap_avail, play_avail, used;
|
||||
int events, revents;
|
||||
|
||||
*status = -1;
|
||||
*status = 0;
|
||||
*iodelay = 0;
|
||||
|
||||
need_capture = need_playback = 0;
|
||||
cap_avail = play_avail = 0;
|
||||
|
||||
if (driver->capture_channels != 0)
|
||||
need_capture = 1;
|
||||
@ -391,7 +405,7 @@ sndio_driver_wait (sndio_driver_t *driver, int *status, float *iodelay)
|
||||
|
||||
while (need_capture || need_playback)
|
||||
{
|
||||
events = 0;
|
||||
events = revents = 0;
|
||||
if (need_capture != 0)
|
||||
events |= POLLIN;
|
||||
|
||||
@ -402,10 +416,9 @@ sndio_driver_wait (sndio_driver_t *driver, int *status, float *iodelay)
|
||||
if (snfds != sio_pollfd(driver->hdl, &pfd, events)) {
|
||||
jack_error("sndio_driver: sio_pollfd failed: %s@%i",
|
||||
__FILE__, __LINE__);
|
||||
*status = -1;
|
||||
*status = -3;
|
||||
return 0;
|
||||
}
|
||||
|
||||
nfds = poll(&pfd, snfds, driver->poll_timeout);
|
||||
if (nfds == -1)
|
||||
{
|
||||
@ -429,36 +442,56 @@ sndio_driver_wait (sndio_driver_t *driver, int *status, float *iodelay)
|
||||
if (revents & POLLOUT)
|
||||
need_playback = 0;
|
||||
|
||||
if (need_capture)
|
||||
if (sio_eof(driver->hdl))
|
||||
{
|
||||
cap_avail = driver->realpos - driver->cappos;
|
||||
jack_error("sndio_driver: sndio error");
|
||||
*status = -5; /* restart */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (cap_avail >= driver->buffer_fill)
|
||||
if (driver->capture_channels > 0)
|
||||
{
|
||||
used = 0;
|
||||
if (driver->realpos > driver->cappos)
|
||||
used = driver->realpos - driver->cappos;
|
||||
cap_avail = used;
|
||||
if (cap_avail > driver->buffer_fill)
|
||||
{
|
||||
jack_error("sndio_driver: capture overrun");
|
||||
*status = -5;
|
||||
return 0;
|
||||
}
|
||||
else if (cap_avail >= driver->period_size)
|
||||
{
|
||||
need_capture = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (need_playback)
|
||||
if (driver->playback_channels > 0)
|
||||
{
|
||||
play_avail = driver->playpos - driver->realpos;
|
||||
|
||||
if (play_avail >= driver->buffer_fill)
|
||||
used = 0;
|
||||
if (driver->playpos > driver->realpos)
|
||||
used = driver->playpos - driver->realpos;
|
||||
play_avail = driver->buffer_fill - used;
|
||||
if (play_avail > driver->buffer_fill)
|
||||
{
|
||||
jack_error("sndio_driver: playback underrun");
|
||||
}
|
||||
}
|
||||
|
||||
if (driver->capture_channels > 0 &&
|
||||
driver->playback_channels > 0)
|
||||
{
|
||||
if ((driver->realpos > 0 &&
|
||||
(play_avail != driver->period_size ||
|
||||
cap_avail != driver->period_size) &&
|
||||
!(!play_avail && !cap_avail && !need_playback &&
|
||||
need_capture)) ||
|
||||
(driver->realpos == 0 &&
|
||||
!play_avail && !cap_avail && need_playback &&
|
||||
!need_capture))
|
||||
{
|
||||
jack_error("sndio_driver: out of sync: "
|
||||
"rp=%lld pa=%lld ca=%lld np=%d nc=%d",
|
||||
driver->realpos, play_avail, cap_avail,
|
||||
need_playback, need_capture);
|
||||
*status = -5;
|
||||
return 0;
|
||||
}
|
||||
else if (play_avail >= driver->period_size)
|
||||
{
|
||||
need_playback = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -473,8 +506,6 @@ sndio_driver_wait (sndio_driver_t *driver, int *status, float *iodelay)
|
||||
|
||||
driver->last_wait_ust = poll_ret;
|
||||
|
||||
*status = 0;
|
||||
|
||||
return driver->period_size;
|
||||
}
|
||||
|
||||
@ -504,8 +535,8 @@ sndio_driver_run_cycle (sndio_driver_t *driver)
|
||||
sndio_driver_set_parameters(driver);
|
||||
sndio_driver_start(driver);
|
||||
|
||||
now = jack_get_microseconds();
|
||||
if (now > driver->poll_next)
|
||||
if (driver->poll_next &&
|
||||
(now = jack_get_microseconds()) > driver->poll_next)
|
||||
{
|
||||
iodelay = now - driver->poll_next;
|
||||
driver->poll_next = now + driver->period_usecs;
|
||||
@ -732,7 +763,7 @@ sndio_driver_detach (sndio_driver_t *driver)
|
||||
static int
|
||||
sndio_driver_read (sndio_driver_t *driver, jack_nframes_t nframes)
|
||||
{
|
||||
jack_nframes_t nbytes;
|
||||
jack_nframes_t nbytes, offset;
|
||||
int channel;
|
||||
size_t io_res;
|
||||
jack_sample_t *portbuf;
|
||||
@ -769,17 +800,18 @@ sndio_driver_read (sndio_driver_t *driver, jack_nframes_t nframes)
|
||||
channel++;
|
||||
}
|
||||
|
||||
io_res = offset = 0;
|
||||
nbytes = nframes * driver->capture_channels * driver->sample_bytes;
|
||||
io_res = 0;
|
||||
while (nbytes > 0)
|
||||
{
|
||||
io_res = sio_read(driver->hdl, driver->capbuf, nbytes);
|
||||
io_res = sio_read(driver->hdl, driver->capbuf + offset, nbytes);
|
||||
if (io_res == 0)
|
||||
{
|
||||
jack_error("sndio_driver: sio_read() failed: %s@%i",
|
||||
__FILE__, __LINE__);
|
||||
break;
|
||||
}
|
||||
offset += io_res;
|
||||
nbytes -= io_res;
|
||||
}
|
||||
driver->cappos += nframes;
|
||||
@ -793,7 +825,7 @@ sndio_driver_write (sndio_driver_t *driver, jack_nframes_t nframes)
|
||||
{
|
||||
jack_nframes_t nbytes;
|
||||
int channel;
|
||||
size_t io_res;
|
||||
size_t io_res, offset;
|
||||
jack_sample_t *portbuf;
|
||||
JSList *node;
|
||||
jack_port_t *port;
|
||||
@ -832,16 +864,17 @@ sndio_driver_write (sndio_driver_t *driver, jack_nframes_t nframes)
|
||||
}
|
||||
|
||||
nbytes = nframes * driver->playback_channels * driver->sample_bytes;
|
||||
io_res = 0;
|
||||
io_res = offset = 0;
|
||||
while (nbytes > 0)
|
||||
{
|
||||
io_res = sio_write(driver->hdl, driver->playbuf, nbytes);
|
||||
io_res = sio_write(driver->hdl, driver->playbuf + offset, nbytes);
|
||||
if (io_res == 0)
|
||||
{
|
||||
jack_error("sndio_driver: sio_write() failed: %s@%i",
|
||||
__FILE__, __LINE__);
|
||||
break;
|
||||
}
|
||||
offset += io_res;
|
||||
nbytes -= io_res;
|
||||
}
|
||||
driver->playpos += nframes;
|
||||
|
Loading…
Reference in New Issue
Block a user