From owner-svn-ports-all@freebsd.org Sat Aug 20 15:48:41 2016 Return-Path: Delivered-To: svn-ports-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C82B3BC0B6D; Sat, 20 Aug 2016 15:48:41 +0000 (UTC) (envelope-from pawel@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 892351A5D; Sat, 20 Aug 2016 15:48:41 +0000 (UTC) (envelope-from pawel@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u7KFmexc019392; Sat, 20 Aug 2016 15:48:40 GMT (envelope-from pawel@FreeBSD.org) Received: (from pawel@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u7KFmeT9019386; Sat, 20 Aug 2016 15:48:40 GMT (envelope-from pawel@FreeBSD.org) Message-Id: <201608201548.u7KFmeT9019386@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: pawel set sender to pawel@FreeBSD.org using -f From: Pawel Pekala Date: Sat, 20 Aug 2016 15:48:40 +0000 (UTC) To: ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org Subject: svn commit: r420515 - in head/audio/sndio: . files X-SVN-Group: ports-head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-ports-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SVN commit messages for the ports tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 20 Aug 2016 15:48:41 -0000 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 # 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 ++ * Copyright (c) 2016 Tobias Kortkamp + * + * 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 +#include ++#include +#include +#include + @@ -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