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
|
SHARED_ONLY = Yes
|
||||||
|
|
||||||
@ -6,7 +6,7 @@ COMMENT = low latency sound server
|
|||||||
|
|
||||||
V = 0.116.1
|
V = 0.116.1
|
||||||
DISTNAME = jack-audio-connection-kit-${V}
|
DISTNAME = jack-audio-connection-kit-${V}
|
||||||
PKGNAME = jack-${V}p1
|
PKGNAME = jack-${V}p2
|
||||||
|
|
||||||
SHARED_LIBS += jack 0.0 # 0.28
|
SHARED_LIBS += jack 0.0 # 0.28
|
||||||
SHARED_LIBS += jackserver 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
|
static void
|
||||||
sndio_driver_write_silence (sndio_driver_t *driver, jack_nframes_t nframes)
|
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;
|
void *localbuf;
|
||||||
|
|
||||||
localsize = nframes * driver->sample_bytes * driver->playback_channels;
|
localsize = nframes * driver->sample_bytes * driver->playback_channels;
|
||||||
@ -164,13 +164,20 @@ sndio_driver_write_silence (sndio_driver_t *driver, jack_nframes_t nframes)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
offset = 0;
|
||||||
bzero(localbuf, localsize);
|
bzero(localbuf, localsize);
|
||||||
io_res = sio_write(driver->hdl, localbuf, localsize);
|
nbytes = localsize;
|
||||||
if (io_res < localsize)
|
while (nbytes > 0)
|
||||||
{
|
{
|
||||||
jack_error("sndio_driver: sio_write() failed: "
|
io_res = sio_write(driver->hdl, localbuf, nbytes);
|
||||||
"count=%d/%d: %s@%i", io_res, localsize,
|
if (io_res == 0)
|
||||||
__FILE__, __LINE__);
|
{
|
||||||
|
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;
|
driver->playpos += nframes;
|
||||||
free(localbuf);
|
free(localbuf);
|
||||||
@ -180,7 +187,7 @@ sndio_driver_write_silence (sndio_driver_t *driver, jack_nframes_t nframes)
|
|||||||
static void
|
static void
|
||||||
sndio_driver_read_silence (sndio_driver_t *driver, jack_nframes_t nframes)
|
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;
|
void *localbuf;
|
||||||
|
|
||||||
localsize = nframes * driver->sample_bytes * driver->capture_channels;
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
offset = 0;
|
||||||
bzero(localbuf, localsize);
|
bzero(localbuf, localsize);
|
||||||
io_res = sio_read(driver->hdl, localbuf, localsize);
|
nbytes = localsize;
|
||||||
if (io_res < localsize)
|
while (nbytes > 0) {
|
||||||
{
|
io_res = sio_read(driver->hdl, localbuf + offset, nbytes);
|
||||||
jack_error("sndio_driver: sio_read() failed: "
|
if (io_res == 0) {
|
||||||
"count=%d/%d: %s@%i", io_res, localsize,
|
jack_error("sndio_driver: sio_read() failed: "
|
||||||
__FILE__, __LINE__);
|
"count=%d/%d: %s@%i", io_res, nbytes,
|
||||||
|
__FILE__, __LINE__);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
offset +=- io_res;
|
||||||
|
nbytes -= io_res;
|
||||||
}
|
}
|
||||||
driver->cappos += nframes;
|
driver->cappos += nframes;
|
||||||
free(localbuf);
|
free(localbuf);
|
||||||
@ -215,8 +228,9 @@ sndio_driver_start (sndio_driver_t *driver)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* prime playback buffers */
|
/* prime playback buffers */
|
||||||
sndio_driver_write_silence(driver,
|
if (driver->playback_channels > 0) {
|
||||||
driver->buffer_fill);
|
sndio_driver_write_silence(driver, driver->buffer_fill);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -255,7 +269,6 @@ sndio_driver_set_parameters (sndio_driver_t *driver)
|
|||||||
par.rate = driver->sample_rate;
|
par.rate = driver->sample_rate;
|
||||||
par.appbufsz = driver->period_size * driver->nperiods;
|
par.appbufsz = driver->period_size * driver->nperiods;
|
||||||
par.round = driver->period_size;
|
par.round = driver->period_size;
|
||||||
// par.xrun = SIO_SYNC;
|
|
||||||
|
|
||||||
if (!sio_setpar(driver->hdl, &par))
|
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_enter;
|
||||||
jack_time_t poll_ret;
|
jack_time_t poll_ret;
|
||||||
int need_capture, need_playback;
|
int need_capture, need_playback;
|
||||||
int cap_avail, play_avail;
|
long long cap_avail, play_avail, used;
|
||||||
int events, revents;
|
int events, revents;
|
||||||
|
|
||||||
*status = -1;
|
*status = 0;
|
||||||
*iodelay = 0;
|
*iodelay = 0;
|
||||||
|
|
||||||
need_capture = need_playback = 0;
|
need_capture = need_playback = 0;
|
||||||
|
cap_avail = play_avail = 0;
|
||||||
|
|
||||||
if (driver->capture_channels != 0)
|
if (driver->capture_channels != 0)
|
||||||
need_capture = 1;
|
need_capture = 1;
|
||||||
@ -391,7 +405,7 @@ sndio_driver_wait (sndio_driver_t *driver, int *status, float *iodelay)
|
|||||||
|
|
||||||
while (need_capture || need_playback)
|
while (need_capture || need_playback)
|
||||||
{
|
{
|
||||||
events = 0;
|
events = revents = 0;
|
||||||
if (need_capture != 0)
|
if (need_capture != 0)
|
||||||
events |= POLLIN;
|
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)) {
|
if (snfds != sio_pollfd(driver->hdl, &pfd, events)) {
|
||||||
jack_error("sndio_driver: sio_pollfd failed: %s@%i",
|
jack_error("sndio_driver: sio_pollfd failed: %s@%i",
|
||||||
__FILE__, __LINE__);
|
__FILE__, __LINE__);
|
||||||
*status = -1;
|
*status = -3;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
nfds = poll(&pfd, snfds, driver->poll_timeout);
|
nfds = poll(&pfd, snfds, driver->poll_timeout);
|
||||||
if (nfds == -1)
|
if (nfds == -1)
|
||||||
{
|
{
|
||||||
@ -429,36 +442,56 @@ sndio_driver_wait (sndio_driver_t *driver, int *status, float *iodelay)
|
|||||||
if (revents & POLLOUT)
|
if (revents & POLLOUT)
|
||||||
need_playback = 0;
|
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");
|
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;
|
used = 0;
|
||||||
|
if (driver->playpos > driver->realpos)
|
||||||
if (play_avail >= driver->buffer_fill)
|
used = driver->playpos - driver->realpos;
|
||||||
|
play_avail = driver->buffer_fill - used;
|
||||||
|
if (play_avail > driver->buffer_fill)
|
||||||
{
|
{
|
||||||
jack_error("sndio_driver: playback underrun");
|
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;
|
*status = -5;
|
||||||
return 0;
|
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;
|
driver->last_wait_ust = poll_ret;
|
||||||
|
|
||||||
*status = 0;
|
|
||||||
|
|
||||||
return driver->period_size;
|
return driver->period_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -504,8 +535,8 @@ sndio_driver_run_cycle (sndio_driver_t *driver)
|
|||||||
sndio_driver_set_parameters(driver);
|
sndio_driver_set_parameters(driver);
|
||||||
sndio_driver_start(driver);
|
sndio_driver_start(driver);
|
||||||
|
|
||||||
now = jack_get_microseconds();
|
if (driver->poll_next &&
|
||||||
if (now > driver->poll_next)
|
(now = jack_get_microseconds()) > driver->poll_next)
|
||||||
{
|
{
|
||||||
iodelay = now - driver->poll_next;
|
iodelay = now - driver->poll_next;
|
||||||
driver->poll_next = now + driver->period_usecs;
|
driver->poll_next = now + driver->period_usecs;
|
||||||
@ -732,7 +763,7 @@ sndio_driver_detach (sndio_driver_t *driver)
|
|||||||
static int
|
static int
|
||||||
sndio_driver_read (sndio_driver_t *driver, jack_nframes_t nframes)
|
sndio_driver_read (sndio_driver_t *driver, jack_nframes_t nframes)
|
||||||
{
|
{
|
||||||
jack_nframes_t nbytes;
|
jack_nframes_t nbytes, offset;
|
||||||
int channel;
|
int channel;
|
||||||
size_t io_res;
|
size_t io_res;
|
||||||
jack_sample_t *portbuf;
|
jack_sample_t *portbuf;
|
||||||
@ -769,17 +800,18 @@ sndio_driver_read (sndio_driver_t *driver, jack_nframes_t nframes)
|
|||||||
channel++;
|
channel++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
io_res = offset = 0;
|
||||||
nbytes = nframes * driver->capture_channels * driver->sample_bytes;
|
nbytes = nframes * driver->capture_channels * driver->sample_bytes;
|
||||||
io_res = 0;
|
|
||||||
while (nbytes > 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)
|
if (io_res == 0)
|
||||||
{
|
{
|
||||||
jack_error("sndio_driver: sio_read() failed: %s@%i",
|
jack_error("sndio_driver: sio_read() failed: %s@%i",
|
||||||
__FILE__, __LINE__);
|
__FILE__, __LINE__);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
offset += io_res;
|
||||||
nbytes -= io_res;
|
nbytes -= io_res;
|
||||||
}
|
}
|
||||||
driver->cappos += nframes;
|
driver->cappos += nframes;
|
||||||
@ -793,7 +825,7 @@ sndio_driver_write (sndio_driver_t *driver, jack_nframes_t nframes)
|
|||||||
{
|
{
|
||||||
jack_nframes_t nbytes;
|
jack_nframes_t nbytes;
|
||||||
int channel;
|
int channel;
|
||||||
size_t io_res;
|
size_t io_res, offset;
|
||||||
jack_sample_t *portbuf;
|
jack_sample_t *portbuf;
|
||||||
JSList *node;
|
JSList *node;
|
||||||
jack_port_t *port;
|
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;
|
nbytes = nframes * driver->playback_channels * driver->sample_bytes;
|
||||||
io_res = 0;
|
io_res = offset = 0;
|
||||||
while (nbytes > 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)
|
if (io_res == 0)
|
||||||
{
|
{
|
||||||
jack_error("sndio_driver: sio_write() failed: %s@%i",
|
jack_error("sndio_driver: sio_write() failed: %s@%i",
|
||||||
__FILE__, __LINE__);
|
__FILE__, __LINE__);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
offset += io_res;
|
||||||
nbytes -= io_res;
|
nbytes -= io_res;
|
||||||
}
|
}
|
||||||
driver->playpos += nframes;
|
driver->playpos += nframes;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user