diff -x '*.o' -r -pu sndio-1.8.1/libsndio/sio_sun.c sndio-1.8.1-work/libsndio/sio_sun.c
--- sndio-1.8.1/libsndio/sio_sun.c	2021-06-16 09:32:46.000000000 +0200
+++ sndio-1.8.1-work/libsndio/sio_sun.c	2022-03-12 10:42:07.184387437 +0100
@@ -76,17 +76,113 @@ static struct sio_ops sio_sun_ops = {
 	NULL, /* getvol */
 };
 
+#ifdef __NetBSD__
+struct audio_swpar {
+	unsigned int sig;
+	unsigned int le;
+	unsigned int bits;
+	unsigned int bps;
+	unsigned int msb;
+	unsigned int rate;
+	unsigned int pchan;
+	unsigned int rchan;
+	unsigned int nblks;
+	unsigned int round;
+};
+struct audio_pos {
+	unsigned int play_pos;
+	unsigned int play_xrun;
+	unsigned int rec_pos;
+	unsigned int rec_xrun;
+};
+#define AUDIO_INITPAR(ap) memset(ap,0,sizeof(struct audio_swpar))
+static int
+netbsd_setpar(int fd, struct audio_swpar *ap)
+{
+	audio_info_t info;
+	u_int enc, len;
+
+	enc = ap->sig
+	 ? (ap->le ? AUDIO_ENCODING_SLINEAR_LE : AUDIO_ENCODING_SLINEAR_BE)
+	 : (ap->le ? AUDIO_ENCODING_ULINEAR_LE : AUDIO_ENCODING_ULINEAR_BE);
+
+	len = ap->nblks * ap->round * ap->bps;
+
+	AUDIO_INITINFO(&info);
+
+	if (ap->pchan > 0) {
+		info.play.channels = ap->pchan;
+		info.play.sample_rate = ap->rate;
+		info.play.precision = ap->bits;
+		info.play.encoding = enc;
+		// info.play.buffer_size = len * ap->pchan;
+	}
+
+	if (ap->rchan > 0) {
+		info.record.channels = ap->rchan;
+		info.record.sample_rate = ap->rate;
+		info.record.precision = ap->bits;
+		info.record.encoding = enc;
+		info.record.buffer_size = len * ap->rchan;
+	}
+
+	return ioctl(fd, AUDIO_SETINFO, &info);
+}
+
+static int
+netbsd_getpar(int fd, struct audio_swpar *ap)
+{
+	audio_info_t info;
+	audio_prinfo_t *chan;
+	u_int bpf;
+	int rc;
+
+	rc = ioctl(fd, AUDIO_GETINFO, &info);
+	if (rc == -1)
+		return -1;
+
+	ap->pchan = info.play.channels;
+	ap->rchan = info.record.channels;
+
+	chan = ap->pchan > 0 ? &info.play : &info.record;
+
+	ap->sig = chan->encoding == AUDIO_ENCODING_SLINEAR_LE
+	       || chan->encoding == AUDIO_ENCODING_SLINEAR_BE;
+	ap->le  = chan->encoding == AUDIO_ENCODING_SLINEAR_LE
+	       || chan->encoding == AUDIO_ENCODING_ULINEAR_LE;
+	ap->bits = chan->precision;
+	ap->bps = (chan->precision + 7)/8;
+	ap->rate = chan->sample_rate;
+	ap->msb = 0;
+
+	bpf = (ap->pchan > 0 ? ap->pchan : ap->rchan) * ap->bps;
+
+	ap->round = bpf ? info.blocksize / bpf : info.blocksize;
+	ap->nblks = info.blocksize ? chan->buffer_size / info.blocksize : 1;
+
+	return 0;
+}
+#endif
+
 static int
 sio_sun_adjpar(struct sio_sun_hdl *hdl, struct audio_swpar *ap)
 {
 	if (hdl->sio.eof)
 		return 0;
+#ifdef __NetBSD__
+	if (netbsd_setpar(hdl->fd, ap) == -1) {
+#else
 	if (ioctl(hdl->fd, AUDIO_SETPAR, ap) == -1) {
+#endif
 		DPERROR("AUDIO_SETPAR");
 		hdl->sio.eof = 1;
 		return 0;
 	}
+#ifdef __NetBSD__
+	if (netbsd_getpar(hdl->fd, ap) == -1) {
+#else
 	if (ioctl(hdl->fd, AUDIO_GETPAR, ap) == -1) {
+#endif
 		DPERROR("AUDIO_GETPAR");
 		hdl->sio.eof = 1;
 		return 0;
@@ -165,7 +261,11 @@ sio_sun_getcap(struct sio_hdl *sh, struc
 	unsigned int enc_map = 0, rchan_map = 0, pchan_map = 0, rate_map;
 	unsigned int i, j, conf;
 
+#ifdef __NetBSD__
+	if (netbsd_getpar(hdl->fd, &savepar) == -1) {
+#else
 	if (ioctl(hdl->fd, AUDIO_GETPAR, &savepar) == -1) {
+#endif
 		DPERROR("AUDIO_GETPAR");
 		hdl->sio.eof = 1;
 		return 0;
@@ -258,7 +358,11 @@ sio_sun_getcap(struct sio_hdl *sh, struc
 	}
 	cap->nconf = nconf;
 
+#ifdef __NetBSD__
+	if (netbsd_setpar(hdl->fd, &savepar) == -1) {
+#else
 	if (ioctl(hdl->fd, AUDIO_SETPAR, &savepar) == -1) {
+#endif
 		DPERROR("AUDIO_SETPAR");
 		hdl->sio.eof = 1;
 		return 0;
@@ -322,6 +426,9 @@ sio_sun_fdopen(int fd, unsigned int mode
 		return NULL;
 	_sio_create(&hdl->sio, &sio_sun_ops, mode, nbio);
 
+#ifdef __NetBSD__
+	/* XXX? */
+#else
 	/*
 	 * pause the device
 	 */
@@ -330,6 +437,7 @@ sio_sun_fdopen(int fd, unsigned int mode
 		free(hdl);
 		return NULL;
 	}
+#endif
 	hdl->fd = fd;
 	hdl->filling = 0;
 	return (struct sio_hdl *)hdl;
@@ -383,6 +491,9 @@ sio_sun_start(struct sio_hdl *sh)
 		 */
 		hdl->filling = 1;
 	} else {
+#ifdef __NetBSD__
+		/* XXX? */
+#else
 		/*
 		 * no play buffers to fill, start now!
 		 */
@@ -391,6 +502,7 @@ sio_sun_start(struct sio_hdl *sh)
 			hdl->sio.eof = 1;
 			return 0;
 		}
+#endif
 		_sio_onmove_cb(&hdl->sio, 0);
 	}
 	return 1;
@@ -405,11 +517,19 @@ sio_sun_stop(struct sio_hdl *sh)
 		hdl->filling = 0;
 		return 1;
 	}
+#ifdef __NetBSD__
+	if (ioctl(hdl->fd, AUDIO_DRAIN, NULL) == -1) {
+		DPERROR("AUDIO_DRAIN");
+		hdl->sio.eof = 1;
+		return 0;
+	}
+#else
 	if (ioctl(hdl->fd, AUDIO_STOP) == -1) {
 		DPERROR("AUDIO_STOP");
 		hdl->sio.eof = 1;
 		return 0;
 	}
+#endif
 	return 1;
 }
 
@@ -439,9 +559,17 @@ sio_sun_setpar(struct sio_hdl *sh, struc
 	} else if (par->appbufsz != ~0U) {
 		ap.round = par->appbufsz / 2;
 		ap.nblks = 2;
+	} else {
+		ap.round = 512;
+		ap.nblks = 2;
 	}
+#ifdef __NetBSD__
+	if (netbsd_setpar(hdl->fd, &ap) == -1) {
+		DPERROR("netbsd_setpar");
+#else
 	if (ioctl(hdl->fd, AUDIO_SETPAR, &ap) == -1) {
 		DPERROR("AUDIO_SETPAR");
+#endif
 		hdl->sio.eof = 1;
 		return 0;
 	}
@@ -454,8 +582,13 @@ sio_sun_getpar(struct sio_hdl *sh, struc
 	struct sio_sun_hdl *hdl = (struct sio_sun_hdl *)sh;
 	struct audio_swpar ap;
 
+#ifdef __NetBSD__
+	if (netbsd_getpar(hdl->fd, &ap) == -1) {
+		DPERROR("netbsd_getpar");
+#else
 	if (ioctl(hdl->fd, AUDIO_GETPAR, &ap) == -1) {
 		DPERROR("AUDIO_GETPAR");
+#endif
 		hdl->sio.eof = 1;
 		return 0;
 	}
@@ -532,11 +665,15 @@ sio_sun_pollfd(struct sio_hdl *sh, struc
 	if (hdl->filling && hdl->sio.wused == hdl->sio.par.bufsz *
 		hdl->sio.par.pchan * hdl->sio.par.bps) {
 		hdl->filling = 0;
+#ifdef __NetBSD__
+		/* XXX? */
+#else
 		if (ioctl(hdl->fd, AUDIO_START) == -1) {
 			DPERROR("AUDIO_START");
 			hdl->sio.eof = 1;
 			return 0;
 		}
+#endif
 		_sio_onmove_cb(&hdl->sio, 0);
 	}
 	return 1;
@@ -547,20 +684,49 @@ sio_sun_revents(struct sio_hdl *sh, stru
 {
 	struct sio_sun_hdl *hdl = (struct sio_sun_hdl *)sh;
 	struct audio_pos ap;
+#ifdef __NetBSD__
+	audio_offset_t aioff,aooff;
+#endif
 	int dierr = 0, doerr = 0, offset, delta;
 	int revents = pfd->revents;
 
 	if ((pfd->revents & POLLHUP) ||
 	    (pfd->revents & (POLLIN | POLLOUT)) == 0)
 		return pfd->revents;
+#ifdef __NetBSD__
+	if (hdl->sio.mode & SIO_PLAY) {
+		if (ioctl(hdl->fd, AUDIO_GETOOFFS, &aooff) == -1) {
+			DPERROR("sio_sun_revents: GETOOFFS");
+			hdl->sio.eof = 1;
+			return POLLHUP;
+		}
+		ap.play_pos = aooff.samples;
+		ap.play_xrun = 0;
+	}
+	if (hdl->sio.mode & SIO_REC) {
+		if (ioctl(hdl->fd, AUDIO_GETIOFFS, &aioff) == -1) {
+			DPERROR("sio_sun_revents: GETIOFFS");
+			hdl->sio.eof = 1;
+			return POLLHUP;
+		}
+		ap.rec_pos = aioff.samples;
+		ap.rec_xrun = 0;
+	}
+#else
 	if (ioctl(hdl->fd, AUDIO_GETPOS, &ap) == -1) {
 		DPERROR("sio_sun_revents: GETPOS");
 		hdl->sio.eof = 1;
 		return POLLHUP;
 	}
+#endif
 	if (hdl->sio.mode & SIO_PLAY) {
-		delta = (ap.play_pos - hdl->obytes) / hdl->obpf;
-		doerr = (ap.play_xrun - hdl->oerr) / hdl->obpf;
+		if (hdl->obpf > 0) {
+			delta = (ap.play_pos - hdl->obytes) / hdl->obpf;
+			doerr = (ap.play_xrun - hdl->oerr) / hdl->obpf;
+		} else {
+			delta = 0;
+			doerr = 0;
+		}
 		hdl->obytes = ap.play_pos;
 		hdl->oerr = ap.play_xrun;
 		hdl->odelta += delta;
@@ -572,8 +738,13 @@ sio_sun_revents(struct sio_hdl *sh, stru
 			DPRINTFN(2, "play xrun %d\n", doerr);
 	}
 	if (hdl->sio.mode & SIO_REC) {
-		delta = (ap.rec_pos - hdl->ibytes) / hdl->ibpf;
-		dierr = (ap.rec_xrun - hdl->ierr) / hdl->ibpf;
+		if (hdl->ibpf > 0) {
+			delta = (ap.rec_pos - hdl->ibytes) / hdl->ibpf;
+			dierr = (ap.rec_xrun - hdl->ierr) / hdl->ibpf;
+		} else {
+			delta = 0;
+			dierr = 0;
+		}
 		hdl->ibytes = ap.rec_pos;
 		hdl->ierr = ap.rec_xrun;
 		hdl->idelta += delta;
diff -x '*.o' -r -pu sndio-1.8.1/sndiod/file.c sndio-1.8.1-work/sndiod/file.c
--- sndio-1.8.1/sndiod/file.c	2021-06-16 09:32:46.000000000 +0200
+++ sndio-1.8.1-work/sndiod/file.c	2022-03-12 10:36:15.649035003 +0100
@@ -59,7 +59,7 @@
 #include "utils.h"
 
 #define MAXFDS 100
-#define TIMER_MSEC 5
+#define TIMER_MSEC 10
 
 void timo_update(unsigned int);
 void timo_init(void);
