Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 20 Aug 2016 15:48:40 +0000 (UTC)
From:      Pawel Pekala <pawel@FreeBSD.org>
To:        ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org
Subject:   svn commit: r420515 - in head/audio/sndio: . files
Message-ID:  <201608201548.u7KFmeT9019386@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: pawel
Date: Sat Aug 20 15:48:40 2016
New Revision: 420515
URL: https://svnweb.freebsd.org/changeset/ports/420515

Log:
  - Fix high CPU usage while recording and playing at the same time,
    report better sio_onmove deltas [1]
  - Fix issues with underruns when the system is under high load
  - Fix sio_getcap [1]
  - Fallback to /dev/dsp (hw.snd.default_unit) in sndiod and libsndio when no
    other device is specified [1]
  - rc.d script now configures a monitoring sub-device (a fake recording stream
    with a mix of all playback streams) by default [1]
  - Use OPSYS for better portability
  
  PR:		212007 [1]
  Submitted by:	Tobias Kortkamp (maintainer) [1]

Modified:
  head/audio/sndio/Makefile
  head/audio/sndio/files/patch-configure
  head/audio/sndio/files/patch-libsndio_sio.c
  head/audio/sndio/files/patch-libsndio_sio__oss.c
  head/audio/sndio/files/sndiod.in
  head/audio/sndio/pkg-message

Modified: head/audio/sndio/Makefile
==============================================================================
--- head/audio/sndio/Makefile	Sat Aug 20 15:33:59 2016	(r420514)
+++ head/audio/sndio/Makefile	Sat Aug 20 15:48:40 2016	(r420515)
@@ -3,6 +3,7 @@
 
 PORTNAME=	sndio
 PORTVERSION=	1.1.0
+PORTREVISION=	1
 CATEGORIES=	audio
 MASTER_SITES=	http://www.sndio.org/
 
@@ -20,7 +21,7 @@ USE_RC_SUBR=	sndiod
 .include <bsd.port.pre.mk>
 
 # FreeBSD 9.x does not have SOCK_CLOEXEC
-.if ${OSVERSION} < 1000000
+.if ${OPSYS} == FreeBSD && ${OSVERSION} < 1000000
 CFLAGS+=	-DSOCK_CLOEXEC=0
 .endif
 

Modified: head/audio/sndio/files/patch-configure
==============================================================================
--- head/audio/sndio/files/patch-configure	Sat Aug 20 15:33:59 2016	(r420514)
+++ head/audio/sndio/files/patch-configure	Sat Aug 20 15:48:40 2016	(r420515)
@@ -8,7 +8,7 @@
  rmidi=no				# do we want support for raw char dev ?
  precision=16				# aucat/sndiod arithmetic precision
  user=_sndio				# non-privileged user for sndio daemon
-@@ -71,6 +72,14 @@ case `uname` in
+@@ -71,6 +72,15 @@ case `uname` in
  		defs='-DHAVE_ARC4RANDOM -DHAVE_ISSETUGID \\\
  		-DHAVE_STRLCAT -DHAVE_STRLCPY -DHAVE_STRTONUM'
  		;;
@@ -16,14 +16,15 @@
 +		user=_sndio
 +		so="$so libsndio.so"
 +		defs='-DHAVE_ARC4RANDOM -DHAVE_ISSETUGID \\\
-+		-DHAVE_STRLCAT -DHAVE_STRLCPY -DHAVE_STRTONUM'
++		-DHAVE_STRLCAT -DHAVE_STRLCPY -DHAVE_STRTONUM \\\
++		-DDEFAULT_DEV=\\"fallback\\"'
 +		oss=yes
 +		mandir=${prefix}/man
 +		;;
  esac
  
  # shell word separator (none)
-@@ -106,6 +115,12 @@ for i; do
+@@ -106,6 +116,12 @@ for i; do
  	--disable-alsa)
  		alsa=no
  		shift;;
@@ -36,7 +37,7 @@
  	--enable-sun)
  		sun=yes
  		shift;;
-@@ -162,6 +177,13 @@ if [ $alsa = yes ]; then
+@@ -162,6 +178,13 @@ if [ $alsa = yes ]; then
  fi
  
  #
@@ -50,7 +51,7 @@
  # if using Sun API, add corresponding parameters
  #
  if [ $sun = yes ]; then
-@@ -215,6 +237,7 @@ user..................... $user
+@@ -215,6 +238,7 @@ user..................... $user
  libbsd................... $libbsd
  precision................ $precision
  alsa..................... $alsa

Modified: head/audio/sndio/files/patch-libsndio_sio.c
==============================================================================
--- head/audio/sndio/files/patch-libsndio_sio.c	Sat Aug 20 15:33:59 2016	(r420514)
+++ head/audio/sndio/files/patch-libsndio_sio.c	Sat Aug 20 15:48:40 2016	(r420515)
@@ -1,15 +1,23 @@
 --- libsndio/sio.c.orig	2016-01-08 20:51:12 UTC
 +++ libsndio/sio.c
-@@ -64,6 +64,8 @@ sio_open(const char *str, unsigned int m
+@@ -64,17 +64,25 @@ sio_open(const char *str, unsigned int m
  			return hdl;
  #if defined(USE_SUN)
  		return _sio_sun_open("rsnd/0", mode, nbio);
 +#elif defined(USE_OSS)
-+		return _sio_oss_open("rsnd/0", mode, nbio);
++		return _sio_oss_open("fallback", mode, nbio);
  #elif defined(USE_ALSA)
  		return _sio_alsa_open("rsnd/0", mode, nbio);
  #else
-@@ -75,6 +77,8 @@ sio_open(const char *str, unsigned int m
+ 		return NULL;
+ #endif
+ 	}
++#if defined(USE_OSS)
++	if (strcmp(str, "fallback") == 0)
++		return _sio_oss_open(str, mode, nbio);
++#endif
+ 	if (_sndio_parsetype(str, "snd"))
+ 		return _sio_aucat_open(str, mode, nbio);
  	if (_sndio_parsetype(str, "rsnd"))
  #if defined(USE_SUN)
  		return _sio_sun_open(str, mode, nbio);

Modified: head/audio/sndio/files/patch-libsndio_sio__oss.c
==============================================================================
--- head/audio/sndio/files/patch-libsndio_sio__oss.c	Sat Aug 20 15:33:59 2016	(r420514)
+++ head/audio/sndio/files/patch-libsndio_sio__oss.c	Sat Aug 20 15:48:40 2016	(r420515)
@@ -1,9 +1,10 @@
---- libsndio/sio_oss.c.orig	2016-07-29 14:09:21 UTC
+--- libsndio/sio_oss.c.orig	2016-08-20 02:30:22 UTC
 +++ libsndio/sio_oss.c
-@@ -0,0 +1,890 @@
+@@ -0,0 +1,838 @@
 +/*	$OpenBSD$	*/
 +/*
 + * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
++ * Copyright (c) 2016 Tobias Kortkamp <t@tobik.me>
 + *
 + * Permission to use, copy, modify, and distribute this software for any
 + * purpose with or without fee is hereby granted, provided that the above
@@ -21,6 +22,7 @@
 +#ifdef USE_OSS
 +#include <sys/types.h>
 +#include <sys/ioctl.h>
++#include <sys/param.h>
 +#include <sys/soundcard.h>
 +#include <sys/stat.h>
 +
@@ -42,13 +44,6 @@
 +	sizeof(DEVPATH_PREFIX) - 1 +	\
 +	sizeof(int) * 3)
 +
-+struct audio_pos {
-+	unsigned int play_pos;  /* total bytes played */
-+	unsigned int play_xrun; /* bytes of silence inserted */
-+	unsigned int rec_pos;   /* total bytes recorded */
-+	unsigned int rec_xrun;  /* bytes dropped */
-+};
-+
 +#define AUDIO_INITPAR(p)						\
 +	(void)memset((void *)(p), 0xff, sizeof(struct audio_swpar))
 +
@@ -72,13 +67,16 @@
 +struct sio_oss_hdl {
 +	struct sio_hdl sio;
 +	int fd;
-+	int filling;
 +	unsigned int ibpf, obpf;	/* bytes per frame */
-+	unsigned int ibytes, obytes;	/* bytes the hw transferred */
-+	unsigned int ierr, oerr;	/* frames the hw dropped */
++	unsigned int isamples;
++	unsigned int osamples;
 +	int idelta, odelta;		/* position reported to client */
 +
-+	unsigned int play_pos;
++	char *devstr;
++
++	/* OSS doesn't have an API to ask for device parameters
++	 * without setting them, so we keep track of them ourselves.
++	 */
 +	struct audio_swpar swpar;
 +};
 +
@@ -95,11 +93,9 @@
 +static int sio_oss_revents(struct sio_hdl *, struct pollfd *);
 +
 +static void sio_oss_fmt_to_swpar(int, struct audio_swpar *);
-+static int sio_oss_audio_getpos(struct sio_oss_hdl *, struct audio_pos *);
 +static int sio_oss_audio_getpar(struct sio_oss_hdl *, struct audio_swpar *);
 +static int sio_oss_audio_setpar(struct sio_oss_hdl *, struct audio_swpar *);
-+static int sio_oss_audio_start(struct sio_oss_hdl *);
-+static int sio_oss_audio_stop(struct sio_oss_hdl *, int);
++static int sio_oss_reopen(struct sio_oss_hdl *);
 +
 +static struct sio_ops sio_oss_ops = {
 +	sio_oss_close,
@@ -315,25 +311,33 @@
 +	unsigned int devnum;
 +	int fd, flags;
 +
-+	p = _sndio_parsetype(str, "rsnd");
-+	if (p == NULL) {
-+		DPRINTF("sio_oss_getfd: %s: \"rsnd\" expected\n", str);
-+		return -1;
-+	}
-+	switch (*p) {
-+	case '/':
-+		p++;
-+		break;
-+	default:
-+		DPRINTF("sio_oss_getfd: %s: '/' expected\n", str);
-+		return -1;
-+	}
-+	p = _sndio_parsenum(p, &devnum, 255);
-+	if (p == NULL || *p != '\0') {
-+		DPRINTF("sio_oss_getfd: %s: number expected after '/'\n", str);
-+		return -1;
++	if (strcmp(str, "fallback") == 0) {
++		/* On FreeBSD /dev/dsp points to the default unit
++		 * selectable with the hw.snd.default_unit sysctl.
++		 * Use it as fallback device.
++		 */
++		snprintf(path, sizeof(path), DEVPATH_PREFIX);
++	} else {
++		p = _sndio_parsetype(str, "rsnd");
++		if (p == NULL) {
++			DPRINTF("sio_oss_getfd: %s: \"rsnd\" expected\n", str);
++			return -1;
++		}
++		switch (*p) {
++		case '/':
++			p++;
++			break;
++		default:
++			DPRINTF("sio_oss_getfd: %s: '/' expected\n", str);
++			return -1;
++		}
++		p = _sndio_parsenum(p, &devnum, 255);
++		if (p == NULL || *p != '\0') {
++			DPRINTF("sio_oss_getfd: %s: number expected after '/'\n", str);
++			return -1;
++		}
++		snprintf(path, sizeof(path), DEVPATH_PREFIX "%u", devnum);
 +	}
-+	snprintf(path, sizeof(path), DEVPATH_PREFIX "%u", devnum);
 +	if (mode == (SIO_PLAY | SIO_REC))
 +		flags = O_RDWR;
 +	else
@@ -347,7 +351,7 @@
 +	return fd;
 +}
 +
-+static struct sio_hdl *
++static struct sio_oss_hdl *
 +sio_oss_fdopen(int fd, unsigned int mode, int nbio)
 +{
 +	struct sio_oss_hdl *hdl;
@@ -360,29 +364,30 @@
 +	/* Set default device parameters */
 +	sio_oss_fmt_to_swpar(AFMT_S16_LE, &hdl->swpar);
 +	hdl->swpar.msb = 1;
-+	hdl->swpar.rate = 44100;
++	hdl->swpar.rate = 48000;
 +	hdl->swpar.bps = SIO_BPS(hdl->swpar.bits);
 +	hdl->swpar.pchan = hdl->swpar.rchan = 2;
-+	hdl->swpar.round = 960; // TODO:
-+	hdl->swpar.nblks = 8; // TODO:
 +
 +	hdl->fd = fd;
-+	hdl->filling = 0;
-+	return (struct sio_hdl *)hdl;
++
++	return hdl;
 +}
 +
 +struct sio_hdl *
 +_sio_oss_open(const char *str, unsigned int mode, int nbio)
 +{
-+	struct sio_hdl *hdl;
++	struct sio_oss_hdl *hdl;
 +	int fd;
 +
 +	fd = sio_oss_getfd(str, mode, nbio);
 +	if (fd < 0)
 +		return NULL;
++
 +	hdl = sio_oss_fdopen(fd, mode, nbio);
-+	if (hdl != NULL)
-+		return hdl;
++	if (hdl != NULL) {
++		hdl->devstr = strdup(str);
++		return (struct sio_hdl*)hdl;
++        }
 +	while (close(fd) < 0 && errno == EINTR)
 +		; /* retry */
 +
@@ -396,6 +401,7 @@
 +
 +	while (close(hdl->fd) < 0 && errno == EINTR)
 +		; /* retry */
++	free(hdl->devstr);
 +	free(hdl);
 +}
 +
@@ -403,51 +409,32 @@
 +sio_oss_start(struct sio_hdl *sh)
 +{
 +	struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh;
++	int low;
 +
 +	hdl->obpf = hdl->sio.par.pchan * hdl->sio.par.bps;
 +	hdl->ibpf = hdl->sio.par.rchan * hdl->sio.par.bps;
-+	hdl->ibytes = 0;
-+	hdl->obytes = 0;
-+	hdl->ierr = 0;
-+	hdl->oerr = 0;
++	hdl->isamples = 0;
++	hdl->osamples = 0;
 +	hdl->idelta = 0;
 +	hdl->odelta = 0;
-+	hdl->play_pos = 0;
 +
-+	if (hdl->sio.mode & SIO_PLAY) {
-+		/*
-+		 * keep the device paused and let sio_oss_pollfd() trigger the
-+		 * start later, to avoid buffer underruns
-+		 */
-+		hdl->filling = 1;
-+	} else {
-+		/*
-+		 * no play buffers to fill, start now!
-+		 */
-+		if (sio_oss_audio_start(hdl) < 0) {
-+			DPERROR("AUDIO_START");
-+			hdl->sio.eof = 1;
-+			return 0;
-+		}
-+		_sio_onmove_cb(&hdl->sio, 0);
-+	}
++	/* Nothing else to do here, device was just (re-)opened in
++	 * sio_setpar and OSS starts playing/recording on first
++	 * write/read.
++	 */
++	_sio_onmove_cb(&hdl->sio, 0);
++
 +	return 1;
 +}
 +
 +static int
 +sio_oss_stop(struct sio_hdl *sh)
 +{
-+	struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh;
-+
-+	if (hdl->filling) {
-+		hdl->filling = 0;
-+		return 1;
-+	}
-+	if (sio_oss_audio_stop(hdl, hdl->fd) < 0) {
-+		DPERROR("AUDIO_STOP");
-+		hdl->sio.eof = 1;
++	struct sio_oss_hdl *hdl = (struct sio_oss_hdl*)sh;
++	/* Close and reopen device.  This resets CURRENT_IPTR which
++	 * allows us to get a semi-accurate recording position */
++        if (sio_oss_audio_setpar(hdl, &hdl->swpar) < 0)
 +		return 0;
-+	}
 +	return 1;
 +}
 +
@@ -506,7 +493,7 @@
 +	par->pchan = ap.pchan;
 +	par->rchan = ap.rchan;
 +	par->round = ap.round;
-+	par->appbufsz = par->bufsz = ap.nblks * ap.round;
++	par->appbufsz = par->bufsz = ap.round * ap.nblks;
 +	par->xrun = SIO_IGNORE;
 +	return 1;
 +}
@@ -531,6 +518,7 @@
 +		hdl->sio.eof = 1;
 +		return 0;
 +	}
++
 +	return n;
 +}
 +
@@ -552,8 +540,6 @@
 +		return 0;
 +	}
 +
-+	hdl->play_pos += n;
-+
 +	return n;
 +}
 +
@@ -570,16 +556,7 @@
 +
 +	pfd->fd = hdl->fd;
 +	pfd->events = events;
-+	if (hdl->filling && hdl->sio.wused == hdl->sio.par.bufsz *
-+		hdl->sio.par.pchan * hdl->sio.par.bps) {
-+		hdl->filling = 0;
-+		if (sio_oss_audio_start(hdl) < 0) {
-+			DPERROR("AUDIO_START");
-+			hdl->sio.eof = 1;
-+			return 0;
-+		}
-+		_sio_onmove_cb(&hdl->sio, 0);
-+	}
++
 +	return 1;
 +}
 +
@@ -587,61 +564,42 @@
 +sio_oss_revents(struct sio_hdl *sh, struct pollfd *pfd)
 +{
 +	struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh;
-+	struct audio_pos ap;
-+	int dierr = 0, doerr = 0, offset, delta;
++	int delta;
 +	int revents = pfd->revents;
++	long long play_pos, rec_pos;
++	oss_count_t optr, iptr;
 +
 +	if ((pfd->revents & POLLHUP) ||
 +	    (pfd->revents & (POLLIN | POLLOUT)) == 0)
 +		return pfd->revents;
-+	if (sio_oss_audio_getpos(hdl, &ap) < 0) {
-+		DPERROR("sio_oss_revents: GETPOS");
-+		hdl->sio.eof = 1;
-+		return POLLHUP;
-+	}
++
 +	if (hdl->sio.mode & SIO_PLAY) {
-+		delta = (ap.play_pos - hdl->obytes) / hdl->obpf;
-+		doerr = (ap.play_xrun - hdl->oerr) / hdl->obpf;
-+		hdl->obytes = ap.play_pos;
-+		hdl->oerr = ap.play_xrun;
++		if (ioctl(hdl->fd, SNDCTL_DSP_CURRENT_OPTR, &optr) < 0) {
++			DPERROR("sio_oss_revents: ");
++			hdl->sio.eof = 1;
++			return POLLHUP;
++		}
++		play_pos = optr.samples - optr.fifo_samples;
++		delta = play_pos - hdl->osamples;
++		hdl->osamples = play_pos;
 +		hdl->odelta += delta;
 +		if (!(hdl->sio.mode & SIO_REC)) {
 +			hdl->idelta += delta;
-+			dierr = doerr;
 +		}
-+		if (doerr > 0)
-+			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;
-+		hdl->ibytes = ap.rec_pos;
-+		hdl->ierr = ap.rec_xrun;
++		if (ioctl(hdl->fd, SNDCTL_DSP_CURRENT_IPTR, &iptr) < 0) {
++			DPERROR("sio_oss_revents: ");
++			hdl->sio.eof = 1;
++			return POLLHUP;
++		}
++		rec_pos = iptr.samples - iptr.fifo_samples;
++		delta = rec_pos - hdl->isamples;
++		hdl->isamples = rec_pos;
 +		hdl->idelta += delta;
 +		if (!(hdl->sio.mode & SIO_PLAY)) {
 +			hdl->odelta += delta;
-+			doerr = dierr;
 +		}
-+		if (dierr > 0)
-+			DPRINTFN(2, "rec xrun %d\n", dierr);
-+	}
-+
-+	/*
-+	 * GETPOS reports positions including xruns,
-+	 * so we have to substract to get the real position
-+	 */
-+	hdl->idelta -= dierr;
-+	hdl->odelta -= doerr;
-+
-+	offset = doerr - dierr;
-+	if (offset > 0) {
-+		hdl->sio.rdrop += offset * hdl->ibpf;
-+		hdl->idelta -= offset;
-+		DPRINTFN(2, "will drop %d and pause %d\n", offset, doerr);
-+	} else if (offset < 0) {
-+		hdl->sio.wsil += -offset * hdl->obpf;
-+		hdl->odelta -= -offset;
-+		DPRINTFN(2, "will insert %d and pause %d\n", -offset, dierr);
 +	}
 +
 +	delta = (hdl->idelta > hdl->odelta) ? hdl->idelta : hdl->odelta;
@@ -653,26 +611,6 @@
 +	return revents;
 +}
 +
-+static int
-+sio_oss_audio_getpos(struct sio_oss_hdl *hdl, struct audio_pos *ap)
-+{
-+	count_info cio, cii;
-+	oss_count_t optr;
-+
-+	ap->play_pos = hdl->play_pos / hdl->sio.par.bps;
-+	ap->play_xrun = 0;
-+
-+	if (ioctl(hdl->fd, SNDCTL_DSP_GETIPTR, &cii) < 0) {
-+		DPERROR("sio_oss_getpos: GETIPTR");
-+		return -1;
-+	}
-+
-+	ap->rec_pos = cii.bytes;
-+	ap->rec_xrun = 0;
-+
-+	return 0;
-+}
-+
 +static void
 +sio_oss_fmt_to_swpar(int fmt, struct audio_swpar *ap) {
 +	switch(fmt) {
@@ -826,67 +764,77 @@
 +
 +static int sio_oss_audio_setpar(struct sio_oss_hdl *hdl, struct audio_swpar *ap)
 +{
-+	int fmt = sio_oss_swpar_to_fmt(ap);
-+	if (fmt < 0)
-+		return -1;
-+
-+	if (ioctl(hdl->fd, SNDCTL_DSP_SETFMT, &fmt) < 0)
-+		return -1;
-+
-+	sio_oss_fmt_to_swpar(fmt, ap);
++	audio_buf_info bi;
++	int bufsz;
++	int chan;
++	int fmt;
++	int rate;
 +
-+	if (ioctl(hdl->fd, SNDCTL_DSP_SPEED, &ap->rate) < 0)
++	if (sio_oss_reopen(hdl) < 0) {
++		DPERROR("sio_oss_audio_setpar: reopen");
 +		return -1;
++	}
 +
-+	ap->bps = SIO_BPS(ap->bits);
++	ap->msb = ap->msb == -1 ? 0 : ap->msb;
++	ap->sig = ap->sig == -1 ? 1 : ap->sig;
++	ap->bits = ap->bits == -1 ? ap->bps == -1 ? 16 : ap->bps*8 : ap->bits;
++	ap->le = ap->le == -1 ? SIO_LE_NATIVE : ap->le;
++	ap->bps = ap->bps == -1 ? SIO_BPS(ap->bits) : ap->bps;
 +	ap->msb = 0;
++	ap->rate = ap->rate == -1 ? 48000 : ap->rate;
 +
-+	int chan = (hdl->sio.mode & SIO_PLAY) ? ap->pchan : ap->rchan;
-+	if (ioctl(hdl->fd, SNDCTL_DSP_CHANNELS, &chan) < 0)
-+		return -1;
-+
-+	ap->pchan = ap->rchan = chan;
-+
-+	hdl->swpar = *ap;
-+
-+	return 0;
-+}
++	if (ap->bits < 8)
++		ap->bits = 8;
++	if (ap->bits > 32)
++		ap->bits = 32;
++	if (ap->bps < 1)
++		ap->bps = 1;
++	if (ap->bps > 4)
++		ap->bps = 4;
++	if (ap->rate < 4000)
++		ap->rate = 4000;
++	if (ap->rate > 192000)
++		ap->rate = 192000;
 +
-+static int sio_oss_audio_start(struct sio_oss_hdl *hdl) {
-+	// Empty playback buffer
-+	if (ioctl(hdl->fd, SNDCTL_DSP_SKIP, NULL) < 0) {
-+		DPERROR("SNDCTL_DSP_SKIP");
++	fmt = sio_oss_swpar_to_fmt(ap);
++	if (fmt < 0)
++		return -1;
++	if (ioctl(hdl->fd, SNDCTL_DSP_SETFMT, &fmt) < 0) {
++		DPERROR("sio_oss_audio_setpar: SETFMT");
 +		return -1;
 +	}
++	sio_oss_fmt_to_swpar(fmt, ap);
 +
-+	int trigger;
-+
-+	if (hdl->sio.mode & SIO_PLAY) {
-+		trigger = PCM_ENABLE_OUTPUT;
++	if (ioctl(hdl->fd, SNDCTL_DSP_SPEED, &ap->rate) < 0) {
++		DPERROR("sio_oss_audio_setpar: SPEED");
++		return -1;
 +	}
-+	if (hdl->sio.mode & SIO_REC) {
-+		trigger = PCM_ENABLE_INPUT;
-+	} // TODO:
 +
-+	if (ioctl(hdl->fd, SNDCTL_DSP_SETTRIGGER, &trigger)) {
-+		DPERROR("sio_oss_start: SETTRIGGER");
++	chan = ap->pchan == ~0U ? ap->pchan : ap->rchan;
++	chan = chan == -1 ? 2 : chan;
++	if (ioctl(hdl->fd, SNDCTL_DSP_CHANNELS, &chan) < 0) {
++		DPERROR("sio_oss_audio_setpar: CHANNELS");
 +		return -1;
 +	}
++	ap->pchan = ap->rchan = chan;
++
++	ap->nblks = ap->nblks <= 0 ? 8 : ap->nblks;
++	ap->round = ap->round <= 0 ? 960 : ap->round;
++
++	hdl->swpar = *ap;
 +
 +	return 0;
 +}
 +
-+static int sio_oss_audio_stop(struct sio_oss_hdl *hdl, int fd) {
-+	/* Block until buffer is played */
-+	if (ioctl(hdl->fd, SNDCTL_DSP_SYNC, NULL) < 0) {
-+		return -1;
-+	}
-+
-+	// TODO: Check mode and use HALT_{IN,OUT}PUT
-+	if (ioctl(hdl->fd, SNDCTL_DSP_HALT, NULL) < 0) {
++static int sio_oss_reopen(struct sio_oss_hdl *hdl) {
++	/* Reopen device */
++	while (close(hdl->fd) < 0 && errno == EINTR)
++		; /* retry */
++	hdl->fd = sio_oss_getfd(hdl->devstr, hdl->sio.mode, 1);
++	if (hdl->fd < 0) {
++		DPERROR("sio_oss_audio_setpar: reopen");
 +		return -1;
 +	}
-+
 +	return 0;
 +}
 +

Modified: head/audio/sndio/files/sndiod.in
==============================================================================
--- head/audio/sndio/files/sndiod.in	Sat Aug 20 15:33:59 2016	(r420514)
+++ head/audio/sndio/files/sndiod.in	Sat Aug 20 15:48:40 2016	(r420515)
@@ -3,7 +3,7 @@
 # $FreeBSD$
 #
 # PROVIDE: sndiod
-# REQUIRE: NETWORKING sysctl
+# REQUIRE: NETWORKING
 # BEFORE:  DAEMON
 # KEYWORD: shutdown
 
@@ -23,9 +23,8 @@ rcvar=sndiod_enable
 
 load_rc_config $name
 
-_sndiod_devnum=$($SYSCTL -n hw.snd.default_unit)
 : ${sndiod_enable="NO"}
-: ${sndiod_flags="-f rsnd/$_sndiod_devnum"}
+: ${sndiod_flags="-s default -m mon -s monitor"}
 
 command="%%PREFIX%%/bin/sndiod"
 

Modified: head/audio/sndio/pkg-message
==============================================================================
--- head/audio/sndio/pkg-message	Sat Aug 20 15:33:59 2016	(r420514)
+++ head/audio/sndio/pkg-message	Sat Aug 20 15:48:40 2016	(r420515)
@@ -1,28 +1,37 @@
-sndio's OSS support (i.e. local playback support) is highly
+Sndio's OSS support (i.e. local playback/recording support) is highly
 experimental.  If you run into problems please file a bug at
 https://github.com/t6/sndio or send an email to t+sndio@tobik.me.
 
-The recommended way to use this port is to have a remote sndio server
-running on a Linux or OpenBSD host.
+Enable the sndiod server with:
 
-If you want clients to auto-play to your remote sndio server, enable
-sndiod with:
-
-    sysrc sndiod_enable=YES sndiod_flags="-f snd@remotehost/0"
+    sysrc sndiod_enable=YES
     service sndiod start
 
-For local playback simply enabling the sndiod server will suffice
+Please note that by default sndiod is configured with a monitoring
+sub-device i.e. a device through which you can record everything that
+plays through sndiod:
 
-    sysrc sndiod_enable=YES
+    aucat -f snd/0.monitor -o recording.wav
+
+Make sure you override sndiod_flags if this is not wanted:
+
+    sysrc sndiod_flags=""
+
+If you want clients to auto-play to your remote sndio server set
+sndiod_flags accordingly:
+
+    sysrc sndiod_flags="-f snd@remotehost/0"
 
-Alternatively set the AUDIODEVICE environment variable so clients know
-where to stream to
+Alternatively you can always set the AUDIODEVICE environment variable
+so clients know where to stream to:
 
     export AUDIODEVICE=snd@remotehost/0
 
-There is no sndio support in the official FreeBSD ports tree yet.  The
-fork at https://github.com/t6/freebsd-port-sndio contains patches that
-enable sndio support in important ports.
+There is little sndio support in the FreeBSD ports tree right now.  If
+your favourite port is missing support please take a look at the fork
+at https://github.com/t6/freebsd-ports-sndio and
+https://github.com/t6/freebsd-ports-sndio/wiki/Status which contains
+patches that enable sndio support in various ports.
 
 audio/pulseaudio-module-sndio is a PulseAudio module that allows you
 to play to your sndio server.  This is useful for ports that have



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201608201548.u7KFmeT9019386>