- 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]
This commit is contained in:
Pawel Pekala 2016-08-20 15:48:40 +00:00
parent 90fb779629
commit 2eef738073
Notes: svn2git 2021-03-31 03:12:20 +00:00
svn path=/head/; revision=420515
6 changed files with 185 additions and 219 deletions

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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;
+ 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);
+ }
+ 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);
+ 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);
+ audio_buf_info bi;
+ int bufsz;
+ int chan;
+ int fmt;
+ int rate;
+
+ if (sio_oss_reopen(hdl) < 0) {
+ DPERROR("sio_oss_audio_setpar: reopen");
+ return -1;
+ }
+
+ 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;
+
+ 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;
+
+ fmt = sio_oss_swpar_to_fmt(ap);
+ if (fmt < 0)
+ return -1;
+
+ if (ioctl(hdl->fd, SNDCTL_DSP_SETFMT, &fmt) < 0)
+ if (ioctl(hdl->fd, SNDCTL_DSP_SETFMT, &fmt) < 0) {
+ DPERROR("sio_oss_audio_setpar: SETFMT");
+ return -1;
+
+ }
+ sio_oss_fmt_to_swpar(fmt, ap);
+
+ if (ioctl(hdl->fd, SNDCTL_DSP_SPEED, &ap->rate) < 0)
+ if (ioctl(hdl->fd, SNDCTL_DSP_SPEED, &ap->rate) < 0) {
+ DPERROR("sio_oss_audio_setpar: SPEED");
+ return -1;
+ }
+
+ ap->bps = SIO_BPS(ap->bits);
+ ap->msb = 0;
+
+ int chan = (hdl->sio.mode & SIO_PLAY) ? ap->pchan : ap->rchan;
+ if (ioctl(hdl->fd, SNDCTL_DSP_CHANNELS, &chan) < 0)
+ 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_start(struct sio_oss_hdl *hdl) {
+ // Empty playback buffer
+ if (ioctl(hdl->fd, SNDCTL_DSP_SKIP, NULL) < 0) {
+ DPERROR("SNDCTL_DSP_SKIP");
+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;
+ }
+
+ int trigger;
+
+ if (hdl->sio.mode & SIO_PLAY) {
+ trigger = PCM_ENABLE_OUTPUT;
+ }
+ if (hdl->sio.mode & SIO_REC) {
+ trigger = PCM_ENABLE_INPUT;
+ } // TODO:
+
+ if (ioctl(hdl->fd, SNDCTL_DSP_SETTRIGGER, &trigger)) {
+ DPERROR("sio_oss_start: SETTRIGGER");
+ return -1;
+ }
+
+ 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) {
+ return -1;
+ }
+
+ return 0;
+}
+

View file

@ -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"

View file

@ -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.
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"
service sndiod start
For local playback simply enabling the sndiod server will suffice
Enable the sndiod server with:
sysrc sndiod_enable=YES
service sndiod start
Alternatively set the AUDIODEVICE environment variable so clients know
where to stream to
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:
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 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