FreeBSD Bugzilla – Attachment 176617 Details for
Bug 214210
audio/sndio: Update to 1.2.0
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
sndio.diff
sndio.diff (text/plain), 39.93 KB, created by
Tobias Kortkamp
on 2016-11-04 12:14:03 UTC
(
hide
)
Description:
sndio.diff
Filename:
MIME Type:
Creator:
Tobias Kortkamp
Created:
2016-11-04 12:14:03 UTC
Size:
39.93 KB
patch
obsolete
>diff --git a/audio/sndio/Makefile b/audio/sndio/Makefile >index 12dff7b..1d140d5 100644 >--- a/audio/sndio/Makefile >+++ b/audio/sndio/Makefile >@@ -3,7 +3,7 @@ > > PORTNAME= sndio > PORTVERSION= 1.1.0 >-PORTREVISION= 1 >+PORTREVISION= 2 > CATEGORIES= audio > MASTER_SITES= http://www.sndio.org/ > >diff --git a/audio/sndio/files/patch-configure b/audio/sndio/files/patch-configure >index b4980dd..0620b2e 100644 >--- a/audio/sndio/files/patch-configure >+++ b/audio/sndio/files/patch-configure >@@ -1,30 +1,41 @@ > --- configure.orig 2015-12-15 05:28:04 UTC > +++ configure >-@@ -32,6 +32,7 @@ prefix=/usr/local # where to install s >+@@ -20,6 +20,8 @@ Usage: configure [options] >+ --disable-sun disable sun audio backend >+ --enable-rmidi enable character device midi backend [$rmidi] >+ --disable-rmidi disable character device midi backend >++--enable-umidi enable character device midi backend [$umidi] >++--disable-umidi disable character device midi backend >+ --with-libbsd use the libbsd rather than bsd-compat/* >+ --without-libbsd don't use libbsd >+ END >+@@ -32,7 +34,9 @@ prefix=/usr/local # where to install s > so="libsndio.so.\${MAJ}.\${MIN}" # shared libs to build > alsa=no # do we want alsa support ? > sun=no # do we want sun support ? > +oss=no # do we want oss support ? > rmidi=no # do we want support for raw char dev ? >++umidi=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,15 @@ case `uname` in >+ libbsd=no # use libbsd? >+@@ -71,6 +75,15 @@ case `uname` in > defs='-DHAVE_ARC4RANDOM -DHAVE_ISSETUGID \\\ > -DHAVE_STRLCAT -DHAVE_STRLCPY -DHAVE_STRTONUM' > ;; >-+ FreeBSD) >++ DragonFly|FreeBSD) > + user=_sndio > + so="$so libsndio.so" > + defs='-DHAVE_ARC4RANDOM -DHAVE_ISSETUGID \\\ >-+ -DHAVE_STRLCAT -DHAVE_STRLCPY -DHAVE_STRTONUM \\\ >-+ -DDEFAULT_DEV=\\"fallback\\"' >++ -DHAVE_STRLCAT -DHAVE_STRLCPY -DHAVE_STRTONUM' > + oss=yes >++ umidi=yes > + mandir=${prefix}/man > + ;; > esac > > # shell word separator (none) >-@@ -106,6 +116,12 @@ for i; do >+@@ -106,6 +119,12 @@ for i; do > --disable-alsa) > alsa=no > shift;; >@@ -37,7 +48,20 @@ > --enable-sun) > sun=yes > shift;; >-@@ -162,6 +178,13 @@ if [ $alsa = yes ]; then >+@@ -118,6 +137,12 @@ for i; do >+ --disable-rmidi) >+ rmidi=no >+ shift;; >++ --enable-umidi) >++ umidi=yes >++ shift;; >++ --disable-umidi) >++ umidi=no >++ shift;; >+ --privsep-user=*) >+ user="${i#--privsep-user=}" >+ shift;; >+@@ -162,6 +187,13 @@ if [ $alsa = yes ]; then > fi > > # >@@ -51,11 +75,28 @@ > # if using Sun API, add corresponding parameters > # > if [ $sun = yes ]; then >-@@ -215,6 +238,7 @@ user..................... $user >+@@ -176,6 +208,13 @@ if [ $rmidi = yes ]; then >+ fi >+ >+ # >++# if using raw character devices for midi, add corresponding parameters >++# >++if [ $umidi = yes ]; then >++ defs="$defs -DUSE_UMIDI" >++fi >++ >++# >+ # if using libbsd, add corresponding parameters >+ # >+ if [ $libbsd = yes ]; then >+@@ -215,8 +254,10 @@ user..................... $user > libbsd................... $libbsd > precision................ $precision > alsa..................... $alsa > +oss...................... $oss > sun...................... $sun > rmidi.................... $rmidi >++umidi.................... $umidi >+ >+ Do "make && make install" to compile and install sndio > >diff --git a/audio/sndio/files/patch-libsndio_Makefile.in b/audio/sndio/files/patch-libsndio_Makefile.in >index e199ca7..407b8bb 100644 >--- a/audio/sndio/files/patch-libsndio_Makefile.in >+++ b/audio/sndio/files/patch-libsndio_Makefile.in >@@ -1,15 +1,25 @@ > --- libsndio/Makefile.in.orig 2015-12-30 11:54:40 UTC > +++ libsndio/Makefile.in >-@@ -99,7 +99,7 @@ clean: >+@@ -98,8 +98,8 @@ clean: >+ # loader to determine dependencies in a single pass > # > OBJS = debug.o aucat.o \ >- mio.o mio_rmidi.o mio_alsa.o mio_aucat.o \ >+-mio.o mio_rmidi.o mio_alsa.o mio_aucat.o \ > -sio.o sio_alsa.o sio_aucat.o sio_sun.o \ >++mio.o mio_rmidi.o mio_umidi.o mio_alsa.o mio_aucat.o \ > +sio.o sio_alsa.o sio_aucat.o sio_oss.o sio_sun.o \ > issetugid.o strlcat.o strlcpy.o strtonum.o > > .c.o: >-@@ -140,3 +140,5 @@ sio_aucat.o: sio_aucat.c aucat.h amsg.h >+@@ -132,6 +132,7 @@ mio_alsa.o: mio_alsa.c debug.h mio_priv. >+ mio_aucat.o: mio_aucat.c aucat.h amsg.h debug.h mio_priv.h sndio.h \ >+ ../bsd-compat/bsd-compat.h >+ mio_rmidi.o: mio_rmidi.c debug.h mio_priv.h sndio.h >++mio_umidi.o: mio_umidi.c debug.h mio_priv.h sndio.h >+ sio.o: sio.c debug.h sio_priv.h sndio.h \ >+ ../bsd-compat/bsd-compat.h >+ sio_alsa.o: sio_alsa.c debug.h sio_priv.h sndio.h \ >+@@ -140,3 +141,5 @@ sio_aucat.o: sio_aucat.c aucat.h amsg.h > ../bsd-compat/bsd-compat.h > sio_sun.o: sio_sun.c debug.h sio_priv.h sndio.h \ > ../bsd-compat/bsd-compat.h >diff --git a/audio/sndio/files/patch-libsndio_mio.c b/audio/sndio/files/patch-libsndio_mio.c >new file mode 100644 >index 0000000..f605b0e >--- /dev/null >+++ b/audio/sndio/files/patch-libsndio_mio.c >@@ -0,0 +1,20 @@ >+--- libsndio/mio.c.orig 2015-12-09 10:13:10 UTC >++++ libsndio/mio.c >+@@ -55,6 +55,8 @@ mio_open(const char *str, unsigned int m >+ return hdl; >+ #if defined(USE_RMIDI) >+ return _mio_rmidi_open("rmidi/0", mode, nbio); >++#elif defined(USE_UMIDI) >++ return _mio_umidi_open("rmidi/0", mode, nbio); >+ #elif defined(USE_ALSA) >+ return _mio_alsa_open("rmidi/0", mode, nbio); >+ #else >+@@ -68,6 +70,8 @@ mio_open(const char *str, unsigned int m >+ if (_sndio_parsetype(str, "rmidi")) >+ #if defined(USE_RMIDI) >+ return _mio_rmidi_open(str, mode, nbio); >++#elif defined(USE_UMIDI) >++ return _mio_umidi_open(str, mode, nbio); >+ #elif defined(USE_ALSA) >+ return _mio_alsa_open(str, mode, nbio); >+ #else >diff --git a/audio/sndio/files/patch-libsndio_mio__priv.h b/audio/sndio/files/patch-libsndio_mio__priv.h >new file mode 100644 >index 0000000..a5c5b7e >--- /dev/null >+++ b/audio/sndio/files/patch-libsndio_mio__priv.h >@@ -0,0 +1,12 @@ >+--- libsndio/mio_priv.h.orig 2015-12-09 10:13:10 UTC >++++ libsndio/mio_priv.h >+@@ -44,6 +44,9 @@ struct mio_ops { >+ }; >+ >+ struct mio_hdl *_mio_rmidi_open(const char *, unsigned, int); >++#ifdef USE_UMIDI >++struct mio_hdl *_mio_umidi_open(const char *, unsigned, int); >++#endif >+ #ifdef USE_ALSA >+ struct mio_hdl *_mio_alsa_open(const char *, unsigned, int); >+ #endif >diff --git a/audio/sndio/files/patch-libsndio_mio__umidi.c b/audio/sndio/files/patch-libsndio_mio__umidi.c >new file mode 100644 >index 0000000..78bf9f7 >--- /dev/null >+++ b/audio/sndio/files/patch-libsndio_mio__umidi.c >@@ -0,0 +1,222 @@ >+--- libsndio/mio_umidi.c.orig 2016-11-04 12:06:45 UTC >++++ libsndio/mio_umidi.c >+@@ -0,0 +1,219 @@ >++/* $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 >++ * copyright notice and this permission notice appear in all copies. >++ * >++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES >++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF >++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR >++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES >++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN >++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF >++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. >++ */ >++ >++#ifdef USE_UMIDI >++#include <sys/types.h> >++#include <sys/stat.h> >++ >++#include <errno.h> >++#include <fcntl.h> >++#include <limits.h> >++#include <poll.h> >++#include <stdio.h> >++#include <stdlib.h> >++#include <string.h> >++#include <unistd.h> >++ >++#include "debug.h" >++#include "mio_priv.h" >++ >++#define DEVPATH_PREFIX "/dev/umidi" >++#define DEVPATH_MAX (1 + \ >++ sizeof(DEVPATH_PREFIX) - 1 + \ >++ sizeof(int) * 3) >++ >++struct mio_umidi_hdl { >++ struct mio_hdl mio; >++ int fd; >++}; >++ >++static void mio_umidi_close(struct mio_hdl *); >++static size_t mio_umidi_read(struct mio_hdl *, void *, size_t); >++static size_t mio_umidi_write(struct mio_hdl *, const void *, size_t); >++static int mio_umidi_nfds(struct mio_hdl *); >++static int mio_umidi_pollfd(struct mio_hdl *, struct pollfd *, int); >++static int mio_umidi_revents(struct mio_hdl *, struct pollfd *); >++ >++static struct mio_ops mio_umidi_ops = { >++ mio_umidi_close, >++ mio_umidi_write, >++ mio_umidi_read, >++ mio_umidi_nfds, >++ mio_umidi_pollfd, >++ mio_umidi_revents >++}; >++ >++static int >++mio_umidi_getfd(const char *str, unsigned int mode, int nbio) >++{ >++ const char *p; >++ char path[DEVPATH_MAX]; >++ unsigned int devnum; >++ unsigned int subdevnum; >++ int fd, flags; >++ >++ p = _sndio_parsetype(str, "rmidi"); >++ if (p == NULL) { >++ DPRINTF("mio_umidi_getfd: %s: \"rsnd\" expected\n", str); >++ return -1; >++ } >++ switch (*p) { >++ case '/': >++ p++; >++ break; >++ default: >++ DPRINTF("mio_umidi_getfd: %s: '/' expected\n", str); >++ return -1; >++ } >++ p = _sndio_parsenum(p, &devnum, 255); >++ if (p == NULL) { >++ DPRINTF("mio_umidi_getfd: %s: number expected after '/'\n", str); >++ return -1; >++ } >++ switch (*p) { >++ case '.': >++ p++; >++ p = _sndio_parsenum(p, &subdevnum, 255); >++ if (p == NULL || *p != '\0') { >++ DPRINTF("mio_umidi_getfd: %s: number expected after '.'\n", >++ str); >++ return -1; >++ } >++ break; >++ default: >++ subdevnum = 0; >++ } >++ snprintf(path, sizeof(path), DEVPATH_PREFIX "%u.%u", devnum, subdevnum); >++ if (mode == (MIO_IN | MIO_OUT)) >++ flags = O_RDWR; >++ else >++ flags = (mode & MIO_OUT) ? O_WRONLY : O_RDONLY; >++ while ((fd = open(path, flags | O_NONBLOCK | O_CLOEXEC)) < 0) { >++ if (errno == EINTR) >++ continue; >++ DPERROR(path); >++ return -1; >++ } >++ return fd; >++} >++ >++static struct mio_hdl * >++mio_umidi_fdopen(int fd, unsigned int mode, int nbio) >++{ >++ struct mio_umidi_hdl *hdl; >++ >++ hdl = malloc(sizeof(struct mio_umidi_hdl)); >++ if (hdl == NULL) >++ return NULL; >++ _mio_create(&hdl->mio, &mio_umidi_ops, mode, nbio); >++ hdl->fd = fd; >++ return (struct mio_hdl *)hdl; >++} >++ >++struct mio_hdl * >++_mio_umidi_open(const char *str, unsigned int mode, int nbio) >++{ >++ struct mio_hdl *hdl; >++ int fd; >++ >++ fd = mio_umidi_getfd(str, mode, nbio); >++ if (fd < 0) >++ return NULL; >++ hdl = mio_umidi_fdopen(fd, mode, nbio); >++ if (hdl != NULL) >++ return hdl; >++ while (close(fd) < 0 && errno == EINTR) >++ ; /* retry */ >++ return NULL; >++} >++ >++static void >++mio_umidi_close(struct mio_hdl *sh) >++{ >++ struct mio_umidi_hdl *hdl = (struct mio_umidi_hdl *)sh; >++ int rc; >++ >++ do { >++ rc = close(hdl->fd); >++ } while (rc < 0 && errno == EINTR); >++ free(hdl); >++} >++ >++static size_t >++mio_umidi_read(struct mio_hdl *sh, void *buf, size_t len) >++{ >++ struct mio_umidi_hdl *hdl = (struct mio_umidi_hdl *)sh; >++ ssize_t n; >++ >++ while ((n = read(hdl->fd, buf, len)) < 0) { >++ if (errno == EINTR) >++ continue; >++ if (errno != EAGAIN) { >++ DPERROR("mio_umidi_read: read"); >++ hdl->mio.eof = 1; >++ } >++ return 0; >++ } >++ if (n == 0) { >++ DPRINTF("mio_umidi_read: eof\n"); >++ hdl->mio.eof = 1; >++ return 0; >++ } >++ return n; >++} >++ >++static size_t >++mio_umidi_write(struct mio_hdl *sh, const void *buf, size_t len) >++{ >++ struct mio_umidi_hdl *hdl = (struct mio_umidi_hdl *)sh; >++ ssize_t n; >++ >++ while ((n = write(hdl->fd, buf, len)) < 0) { >++ if (errno == EINTR) >++ continue; >++ if (errno != EAGAIN) { >++ DPERROR("mio_umidi_write: write"); >++ hdl->mio.eof = 1; >++ } >++ return 0; >++ } >++ return n; >++} >++ >++static int >++mio_umidi_nfds(struct mio_hdl *sh) >++{ >++ return 1; >++} >++ >++static int >++mio_umidi_pollfd(struct mio_hdl *sh, struct pollfd *pfd, int events) >++{ >++ struct mio_umidi_hdl *hdl = (struct mio_umidi_hdl *)sh; >++ >++ pfd->fd = hdl->fd; >++ pfd->events = events; >++ return 1; >++} >++ >++static int >++mio_umidi_revents(struct mio_hdl *sh, struct pollfd *pfd) >++{ >++ return pfd->revents; >++} >++#endif /* defined USE_UMIDI */ >diff --git a/audio/sndio/files/patch-libsndio_sio.c b/audio/sndio/files/patch-libsndio_sio.c >index 1226d84..44de62a 100644 >--- a/audio/sndio/files/patch-libsndio_sio.c >+++ b/audio/sndio/files/patch-libsndio_sio.c >@@ -1,23 +1,15 @@ > --- libsndio/sio.c.orig 2016-01-08 20:51:12 UTC > +++ libsndio/sio.c >-@@ -64,17 +64,25 @@ sio_open(const char *str, unsigned int m >+@@ -64,6 +64,8 @@ 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("fallback", mode, nbio); >++ return _sio_oss_open("rsnd/0", mode, nbio); > #elif defined(USE_ALSA) > return _sio_alsa_open("rsnd/0", mode, nbio); > #else >- 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); >+@@ -75,6 +77,8 @@ sio_open(const char *str, unsigned int m > if (_sndio_parsetype(str, "rsnd")) > #if defined(USE_SUN) > return _sio_sun_open(str, mode, nbio); >diff --git a/audio/sndio/files/patch-libsndio_sio__oss.c b/audio/sndio/files/patch-libsndio_sio__oss.c >index 90cde18..ba812d7 100644 >--- a/audio/sndio/files/patch-libsndio_sio__oss.c >+++ b/audio/sndio/files/patch-libsndio_sio__oss.c >@@ -1,6 +1,6 @@ >---- libsndio/sio_oss.c.orig 2016-08-20 02:30:22 UTC >+--- libsndio/sio_oss.c.orig 2016-11-04 12:06:45 UTC > +++ libsndio/sio_oss.c >-@@ -0,0 +1,838 @@ >+@@ -0,0 +1,644 @@ > +/* $OpenBSD$ */ > +/* > + * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org> >@@ -20,15 +20,11 @@ > + */ > + > +#ifdef USE_OSS >-+#include <sys/types.h> > +#include <sys/ioctl.h> >-+#include <sys/param.h> > +#include <sys/soundcard.h> >-+#include <sys/stat.h> > + > +#include <errno.h> > +#include <fcntl.h> >-+#include <limits.h> > +#include <poll.h> > +#include <stdio.h> > +#include <stdlib.h> >@@ -44,58 +40,73 @@ > + sizeof(DEVPATH_PREFIX) - 1 + \ > + sizeof(int) * 3) > + >-+#define AUDIO_INITPAR(p) \ >-+ (void)memset((void *)(p), 0xff, sizeof(struct audio_swpar)) >++struct sio_oss_fmt { >++ int fmt; >++ unsigned int bits; >++ unsigned int bps; >++ unsigned int sig; >++ unsigned int le; >++ unsigned int msb; >++}; >++static struct sio_oss_fmt formats[] = { >++ /* See http://manuals.opensound.com/developer/formats.html. >++ * AFMT_{S8,U16}_* are marked as obsolete so are missing here. >++ */ > + >-+/* >-+ * argument to AUDIO_SETPAR and AUDIO_GETPAR ioctls >-+ */ >-+struct audio_swpar { >-+ unsigned int sig; /* if 1, encoding is signed */ >-+ unsigned int le; /* if 1, encoding is little-endian */ >-+ unsigned int bits; /* bits per sample */ >-+ unsigned int bps; /* bytes per sample */ >-+ unsigned int msb; /* if 1, bits are msb-aligned */ >-+ unsigned int rate; /* common play & rec sample rate */ >-+ unsigned int pchan; /* play channels */ >-+ unsigned int rchan; /* rec channels */ >-+ unsigned int nblks; /* number of blocks in play buffer */ >-+ unsigned int round; /* common frames per block */ >-+ unsigned int _spare[6]; >++ /* le+msb not important */ >++ { AFMT_U8, 8, 1, 0, 0, 0 }, >++ { AFMT_U8, 8, 1, 0, 1, 0 }, >++ { AFMT_U8, 8, 1, 0, 0, 1 }, >++ { AFMT_U8, 8, 1, 0, 1, 1 }, >++ >++ /* msb not important */ >++ { AFMT_S16_BE, 16, 2, 1, 0, 0 }, >++ { AFMT_S16_BE, 16, 2, 1, 0, 1 }, >++ { AFMT_S16_LE, 16, 2, 1, 1, 0 }, >++ { AFMT_S16_LE, 16, 2, 1, 1, 1 }, >++ { AFMT_S24_BE, 24, 3, 1, 0, 0 }, >++ { AFMT_S24_BE, 24, 3, 1, 0, 1 }, >++ { AFMT_S24_LE, 24, 3, 1, 1, 0 }, >++ { AFMT_S24_LE, 24, 3, 1, 1, 1 }, >++ { AFMT_U24_BE, 24, 3, 0, 0, 0 }, >++ { AFMT_U24_BE, 24, 3, 0, 0, 1 }, >++ { AFMT_U24_LE, 24, 3, 0, 1, 0 }, >++ { AFMT_U24_LE, 24, 3, 0, 1, 1 }, >++ >++ { AFMT_S32_BE, 32, 4, 1, 0, 1 }, >++ { AFMT_S32_LE, 32, 4, 1, 1, 1 }, >++ { AFMT_U32_BE, 32, 4, 0, 0, 1 }, >++ { AFMT_U32_LE, 32, 4, 0, 1, 1 }, > +}; > + > +struct sio_oss_hdl { > + struct sio_hdl sio; > + int fd; >-+ unsigned int ibpf, obpf; /* bytes per frame */ > + unsigned int isamples; > + unsigned int osamples; >-+ int idelta, odelta; /* position reported to client */ >-+ >-+ char *devstr; >++ int idelta, odelta; > + >-+ /* 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; >++ int fmt; >++ unsigned int rate; >++ unsigned int chan; >++ unsigned int appbufsz; >++ unsigned int round; > +}; > + >-+static void sio_oss_close(struct sio_hdl *); >-+static int sio_oss_start(struct sio_hdl *); >-+static int sio_oss_stop(struct sio_hdl *); >-+static int sio_oss_setpar(struct sio_hdl *, struct sio_par *); >-+static int sio_oss_getpar(struct sio_hdl *, struct sio_par *); >++static struct sio_hdl *sio_oss_fdopen(const char *, int, unsigned int, int); > +static int sio_oss_getcap(struct sio_hdl *, struct sio_cap *); >-+static size_t sio_oss_read(struct sio_hdl *, void *, size_t); >-+static size_t sio_oss_write(struct sio_hdl *, const void *, size_t); >++static int sio_oss_getfd(const char *, unsigned int, int); >++static int sio_oss_getpar(struct sio_hdl *, struct sio_par *); > +static int sio_oss_nfds(struct sio_hdl *); > +static int sio_oss_pollfd(struct sio_hdl *, struct pollfd *, int); > +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_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_reopen(struct sio_oss_hdl *); >++static int sio_oss_setpar(struct sio_hdl *, struct sio_par *); >++static int sio_oss_start(struct sio_hdl *); >++static int sio_oss_stop(struct sio_hdl *); >++static int sio_oss_xrun(struct sio_oss_hdl *); >++static size_t sio_oss_read(struct sio_hdl *, void *, size_t); >++static size_t sio_oss_write(struct sio_hdl *, const void *, size_t); >++static void sio_oss_close(struct sio_hdl *); > + > +static struct sio_ops sio_oss_ops = { > + sio_oss_close, >@@ -113,97 +124,36 @@ > + NULL, /* getvol */ > +}; > + >-+static int >-+sio_oss_adjpar(struct sio_oss_hdl *hdl, struct audio_swpar *ap) >-+{ >-+ if (hdl->sio.eof) >-+ return 0; >-+ if (sio_oss_audio_setpar(hdl, ap)) { >-+ DPERROR("AUDIO_SETPAR"); >-+ hdl->sio.eof = 1; >-+ return 0; >-+ } >-+ if (sio_oss_audio_getpar(hdl, ap)) { >-+ DPERROR("AUDIO_GETPAR"); >-+ hdl->sio.eof = 1; >-+ return 0; >-+ } >-+ return 1; >-+} >-+ >-+/* >-+ * try to set the device to the given parameters and check that the >-+ * device can use them; return 1 on success, 0 on failure or error >-+ */ >-+static int >-+sio_oss_testpar(struct sio_oss_hdl *hdl, struct sio_enc *enc, >-+ unsigned int pchan, unsigned int rchan, unsigned int rate) >-+{ >-+ struct audio_swpar ap; >-+ >-+ AUDIO_INITPAR(&ap); >-+ if (enc != NULL) { >-+ ap.sig = enc->sig; >-+ ap.bits = enc->bits; >-+ ap.bps = enc->bps; >-+ if (ap.bps > 1) >-+ ap.le = enc->le; >-+ if (ap.bps * 8 > ap.bits) >-+ ap.msb = enc->msb; >-+ } >-+ if (rate) >-+ ap.rate = rate; >-+ if (pchan && (hdl->sio.mode & SIO_PLAY)) >-+ ap.pchan = pchan; >-+ if (rchan && (hdl->sio.mode & SIO_REC)) >-+ ap.rchan = rchan; >-+ if (!sio_oss_adjpar(hdl, &ap)) >-+ return 0; >-+ if (pchan && ap.pchan != pchan) >-+ return 0; >-+ if (rchan && ap.rchan != rchan) >-+ return 0; >-+ if (rate && ap.rate != rate) >-+ return 0; >-+ if (enc) { >-+ if (ap.sig != enc->sig) >-+ return 0; >-+ if (ap.bits != enc->bits) >-+ return 0; >-+ if (ap.bps != enc->bps) >-+ return 0; >-+ if (ap.bps > 1 && ap.le != enc->le) >-+ return 0; >-+ if (ap.bits < ap.bps * 8 && ap.msb != enc->msb) >-+ return 0; >-+ } >-+ return 1; >-+} >-+ > +/* > + * guess device capabilities > + */ > +static int > +sio_oss_getcap(struct sio_hdl *sh, struct sio_cap *cap) > +{ >++ /* From sound(4): >++ * The FreeBSD multichannel matrix processor supports up to 18 >++ * interleaved channels, but the limit is currently set to 8 >++ * channels (as commonly used for 7.1 surround sound). >++ */ > + static unsigned int chans[] = { >-+ 1, 2, 4, 6, 8, 10, 12 >++ 1, 2, 4, 6, 8 > + }; > + static unsigned int rates[] = { >-+ 8000, 11025, 12000, 16000, 22050, 24000, >-+ 32000, 44100, 48000, 64000, 88200, 96000 >++ 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, >++ 48000, 64000, 88200, 96000, 192000 > + }; >-+ static unsigned int encs[] = { >-+ 8, 16, 24, 32 >++ static int afmts[] = { >++ AFMT_U8, AFMT_S16_LE, AFMT_S16_BE, AFMT_S24_LE, AFMT_U24_LE, >++ AFMT_S32_LE, AFMT_U32_LE > + }; > + struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh; >-+ struct audio_swpar savepar, ap; > + unsigned int nconf = 0; > + unsigned int enc_map = 0, rchan_map = 0, pchan_map = 0, rate_map; >-+ unsigned int i, j, conf; >++ unsigned int i, j, k, conf; >++ int fmts; > + >-+ if (sio_oss_audio_getpar(hdl, &savepar)) { >-+ DPERROR("AUDIO_GETPAR"); >++ if (ioctl(hdl->fd, SNDCTL_DSP_GETFMTS, &fmts) < 0) { >++ DPERROR("sio_oss_getcap: GETFMTS"); > + hdl->sio.eof = 1; > + return 0; > + } >@@ -211,71 +161,49 @@ > + /* > + * get a subset of supported encodings > + */ >-+ for (i = 0; i < sizeof(encs) / sizeof(encs[0]); i++) { >-+ AUDIO_INITPAR(&ap); >-+ ap.bits = encs[i]; >-+ ap.sig = (ap.bits > 8) ? 1 : 0; >-+ if (!sio_oss_adjpar(hdl, &ap)) >-+ return 0; >-+ if (ap.bits == encs[i]) { >-+ cap->enc[i].sig = ap.sig; >-+ cap->enc[i].bits = ap.bits; >-+ cap->enc[i].le = ap.le; >-+ cap->enc[i].bps = ap.bps; >-+ cap->enc[i].msb = ap.msb; >-+ enc_map |= 1 << i; >++ for (j = 0, i = 0; i < sizeof(afmts) / sizeof(afmts[0]); i++) { >++ if (fmts & afmts[i]) { >++ for (k = 0; k < sizeof(formats) / sizeof(formats[0]); k++) { >++ if (formats[k].fmt == afmts[i]) { >++ cap->enc[j].sig = formats[k].sig; >++ cap->enc[j].bits = formats[k].bits; >++ cap->enc[j].bps = formats[k].bps; >++ cap->enc[j].le = formats[k].le; >++ cap->enc[j].msb = formats[k].msb; >++ enc_map |= 1 << j; >++ j++; >++ break; >++ } >++ } > + } > + } > + > + /* > + * fill channels >-+ * >-+ * for now we're lucky: all kernel devices assume that the >-+ * number of channels and the encoding are independent so we can >-+ * use the current encoding and try various channels. > + */ > + if (hdl->sio.mode & SIO_PLAY) { > + for (i = 0; i < sizeof(chans) / sizeof(chans[0]); i++) { >-+ AUDIO_INITPAR(&ap); >-+ ap.pchan = chans[i]; >-+ if (!sio_oss_adjpar(hdl, &ap)) >-+ return 0; >-+ if (ap.pchan == chans[i]) { >-+ cap->pchan[i] = chans[i]; >-+ pchan_map |= (1 << i); >-+ } >++ cap->pchan[i] = chans[i]; >++ pchan_map |= (1 << i); > + } > + } > + if (hdl->sio.mode & SIO_REC) { > + for (i = 0; i < sizeof(chans) / sizeof(chans[0]); i++) { >-+ AUDIO_INITPAR(&ap); >-+ ap.pchan = chans[i]; >-+ if (!sio_oss_adjpar(hdl, &ap)) >-+ return 0; >-+ if (ap.rchan == chans[i]) { >-+ cap->rchan[i] = chans[i]; >-+ rchan_map |= (1 << i); >-+ } >++ cap->rchan[i] = chans[i]; >++ rchan_map |= (1 << i); > + } > + } > + > + /* > + * fill rates >-+ * >-+ * rates are not independent from other parameters (eg. on >-+ * uaudio devices), so certain rates may not be allowed with >-+ * certain encodings. We have to check rates for all encodings > + */ >-+ for (j = 0; j < sizeof(encs) / sizeof(encs[0]); j++) { >++ for (j = 0; j < sizeof(formats) / sizeof(formats[0]); j++) { > + rate_map = 0; > + if ((enc_map & (1 << j)) == 0) > + continue; > + for (i = 0; i < sizeof(rates) / sizeof(rates[0]); i++) { >-+ if (sio_oss_testpar(hdl, >-+ &cap->enc[j], 0, 0, rates[i])) { >-+ cap->rate[i] = rates[i]; >-+ rate_map |= (1 << i); >-+ } >++ cap->rate[i] = rates[i]; >++ rate_map |= (1 << i); > + } > + for (conf = 0; conf < nconf; conf++) { > + if (cap->confs[conf].rate == rate_map) { >@@ -295,11 +223,6 @@ > + } > + cap->nconf = nconf; > + >-+ if (sio_oss_audio_setpar(hdl, &savepar)) { >-+ DPERROR("AUDIO_SETPAR"); >-+ hdl->sio.eof = 1; >-+ return 0; >-+ } > + return 1; > +} > + >@@ -311,33 +234,25 @@ > + unsigned int devnum; > + int fd, flags; > + >-+ 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); >++ 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); > + if (mode == (SIO_PLAY | SIO_REC)) > + flags = O_RDWR; > + else >@@ -351,8 +266,8 @@ > + return fd; > +} > + >-+static struct sio_oss_hdl * >-+sio_oss_fdopen(int fd, unsigned int mode, int nbio) >++static struct sio_hdl * >++sio_oss_fdopen(const char *str, int fd, unsigned int mode, int nbio) > +{ > + struct sio_oss_hdl *hdl; > + >@@ -362,15 +277,15 @@ > + _sio_create(&hdl->sio, &sio_oss_ops, mode, nbio); > + > + /* Set default device parameters */ >-+ sio_oss_fmt_to_swpar(AFMT_S16_LE, &hdl->swpar); >-+ hdl->swpar.msb = 1; >-+ hdl->swpar.rate = 48000; >-+ hdl->swpar.bps = SIO_BPS(hdl->swpar.bits); >-+ hdl->swpar.pchan = hdl->swpar.rchan = 2; >++ hdl->fmt = AFMT_S16_LE; >++ hdl->rate = 48000; >++ hdl->chan = 2; >++ hdl->round = 960; >++ hdl->appbufsz = 8 * 960; > + > + hdl->fd = fd; > + >-+ return hdl; >++ return (struct sio_hdl *)hdl; > +} > + > +struct sio_hdl * >@@ -383,11 +298,10 @@ > + if (fd < 0) > + return NULL; > + >-+ hdl = sio_oss_fdopen(fd, mode, nbio); >-+ if (hdl != NULL) { >-+ hdl->devstr = strdup(str); >++ hdl = (struct sio_oss_hdl *)sio_oss_fdopen(str, fd, mode, nbio); >++ if (hdl != NULL) > + return (struct sio_hdl*)hdl; >-+ } >++ > + while (close(fd) < 0 && errno == EINTR) > + ; /* retry */ > + >@@ -401,7 +315,6 @@ > + > + while (close(hdl->fd) < 0 && errno == EINTR) > + ; /* retry */ >-+ free(hdl->devstr); > + free(hdl); > +} > + >@@ -409,18 +322,14 @@ > +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->isamples = 0; > + hdl->osamples = 0; > + hdl->idelta = 0; > + hdl->odelta = 0; > + >-+ /* Nothing else to do here, device was just (re-)opened in >-+ * sio_setpar and OSS starts playing/recording on first >-+ * write/read. >++ /* Nothing else to do here. OSS starts playing/recording >++ * on first write/read. > + */ > + _sio_onmove_cb(&hdl->sio, 0); > + >@@ -431,45 +340,95 @@ > +sio_oss_stop(struct sio_hdl *sh) > +{ > + 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; >++ >++ if (ioctl(hdl->fd, SNDCTL_DSP_SYNC, NULL) < 0) { >++ DPERROR("sio_oss_stop: SYNC"); >++ hdl->sio.eof = 1; >++ return 0; >++ } >++ if (ioctl(hdl->fd, SNDCTL_DSP_HALT, NULL) < 0) { >++ DPERROR("sio_oss_stop: HALT"); >++ hdl->sio.eof = 1; >++ return 0; >++ } >++ >++ /* Reset device parameters. When we do not do this, resuming >++ * playback/recording will trigger poll with revents=POLLIN >++ * too often, which leads to sndiod using 100 % CPU. >++ */ >++ return sio_oss_setpar(sh, &hdl->sio.par); > +} > + > +static int > +sio_oss_setpar(struct sio_hdl *sh, struct sio_par *par) > +{ > + struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh; >-+ struct audio_swpar ap; >-+ >-+ AUDIO_INITPAR(&ap); >-+ ap.sig = par->sig; >-+ ap.le = par->le; >-+ ap.bits = par->bits; >-+ ap.bps = par->bps; >-+ ap.msb = par->msb; >-+ ap.rate = par->rate; >++ unsigned int i; >++ int policy; >++ >++ hdl->fmt = AFMT_S16_LE; >++ for (i = 0; i < sizeof(formats)/sizeof(formats[0]); i++) { >++ if (formats[i].bits == par->bits >++ && formats[i].le == par->le >++ && formats[i].sig == par->sig >++ && formats[i].msb == par->msb) { >++ hdl->fmt = formats[i].fmt; >++ break; >++ } >++ } >++ >++ if (par->rate != ~0U) >++ hdl->rate = par->rate; >++ if (hdl->rate < 8000) >++ hdl->rate = 8000; >++ if (hdl->rate > 192000) >++ hdl->rate = 192000; >++ > + if (hdl->sio.mode & SIO_PLAY) >-+ ap.pchan = par->pchan; >-+ if (hdl->sio.mode & SIO_REC) >-+ ap.rchan = par->rchan; >++ hdl->chan = par->pchan; >++ else if (hdl->sio.mode & SIO_REC) >++ hdl->chan = par->rchan; >++ > + if (par->round != ~0U && par->appbufsz != ~0U) { >-+ ap.round = par->round; >-+ ap.nblks = par->appbufsz / par->round; >++ hdl->round = par->round; >++ hdl->appbufsz = par->appbufsz; > + } else if (par->round != ~0U) { >-+ ap.round = par->round; >-+ ap.nblks = 2; >++ hdl->round = par->round; >++ hdl->appbufsz = 2 * par->round; > + } else if (par->appbufsz != ~0U) { >-+ ap.round = par->appbufsz / 2; >-+ ap.nblks = 2; >++ hdl->round = par->appbufsz / 2; >++ hdl->appbufsz = par->appbufsz; >++ } >++ >++ /* Set timing policy to 5 which is OSS' default. The >++ * user-settable hw.snd.latency sysctl influences the default >++ * policy. >++ */ >++ policy = 5; >++ if (ioctl(hdl->fd, SNDCTL_DSP_POLICY, &policy) < 0) { >++ DPERROR("sio_oss_setpar: POLICY"); >++ hdl->sio.eof = 1; >++ return 0; >++ } >++ >++ if (ioctl(hdl->fd, SNDCTL_DSP_SETFMT, &hdl->fmt) < 0) { >++ DPERROR("sio_oss_setpar: SETFMT"); >++ hdl->sio.eof = 1; >++ return 0; >++ } >++ >++ if (ioctl(hdl->fd, SNDCTL_DSP_SPEED, &hdl->rate) < 0) { >++ DPERROR("sio_oss_setpar: SPEED"); >++ hdl->sio.eof = 1; >++ return 0; > + } >-+ if (sio_oss_audio_setpar(hdl, &ap) < 0) { >-+ DPERROR("AUDIO_SETPAR"); >++ >++ if (ioctl(hdl->fd, SNDCTL_DSP_CHANNELS, &hdl->chan) < 0) { >++ DPERROR("sio_oss_setpar: CHANNELS"); > + hdl->sio.eof = 1; > + return 0; > + } >++ > + return 1; > +} > + >@@ -477,24 +436,32 @@ > +sio_oss_getpar(struct sio_hdl *sh, struct sio_par *par) > +{ > + struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh; >-+ struct audio_swpar ap; >-+ >-+ if (sio_oss_audio_getpar(hdl, &ap) < 0) { >-+ DPERROR("AUDIO_GETPAR"); >++ unsigned int i, found = 0; >++ >++ for (i = 0; i < sizeof(formats)/sizeof(formats[0]); i++) { >++ if (formats[i].fmt == hdl->fmt) { >++ par->sig = formats[i].sig; >++ par->le = formats[i].le; >++ par->bits = formats[i].bits; >++ par->bps = formats[i].bps; >++ par->msb = formats[i].msb; >++ found = 1; >++ break; >++ } >++ } >++ if (!found) { >++ DPRINTF("sio_oss_getpar: unknown format %d\n", hdl->fmt); > + hdl->sio.eof = 1; > + return 0; > + } >-+ par->sig = ap.sig; >-+ par->le = ap.le; >-+ par->bits = ap.bits; >-+ par->bps = ap.bps; >-+ par->msb = ap.msb; >-+ par->rate = ap.rate; >-+ par->pchan = ap.pchan; >-+ par->rchan = ap.rchan; >-+ par->round = ap.round; >-+ par->appbufsz = par->bufsz = ap.round * ap.nblks; >++ >++ par->rate = hdl->rate; >++ par->pchan = hdl->chan; >++ par->rchan = hdl->chan; >++ par->round = hdl->round; >++ par->appbufsz = par->bufsz = hdl->appbufsz; > + par->xrun = SIO_IGNORE; >++ > + return 1; > +} > + >@@ -560,10 +527,64 @@ > + return 1; > +} > + >-+int >++static int >++sio_oss_xrun(struct sio_oss_hdl *hdl) >++{ >++ int clk; >++ int wsil, rdrop, cmove; >++ int rbpf, rround; >++ int wbpf; >++ >++ DPRINTFN(2, "sio_oss_xrun:\n"); >++ if (_sndio_debug >= 2) >++ _sio_printpos(&hdl->sio); >++ >++ /* >++ * we assume rused/wused are zero if rec/play modes are not >++ * selected. This allows us to keep the same formula for all >++ * modes, provided we set rbpf/wbpf to 1 to avoid division by >++ * zero. >++ * >++ * to understand the formula, draw a picture :) >++ */ >++ rbpf = (hdl->sio.mode & SIO_REC) ? >++ hdl->sio.par.bps * hdl->sio.par.rchan : 1; >++ wbpf = (hdl->sio.mode & SIO_PLAY) ? >++ hdl->sio.par.bps * hdl->sio.par.pchan : 1; >++ rround = hdl->sio.par.round * rbpf; >++ >++ clk = hdl->sio.cpos % hdl->sio.par.round; >++ rdrop = (clk * rbpf - hdl->sio.rused) % rround; >++ if (rdrop < 0) >++ rdrop += rround; >++ cmove = (rdrop + hdl->sio.rused) / rbpf; >++ wsil = cmove * wbpf + hdl->sio.wused; >++ >++ DPRINTFN(2, "wsil = %d, cmove = %d, rdrop = %d\n", wsil, cmove, rdrop); >++ >++ if (!sio_oss_stop(&hdl->sio)) >++ return 0; >++ if (!sio_oss_start(&hdl->sio)) >++ return 0; >++ if (hdl->sio.mode & SIO_PLAY) { >++ hdl->odelta -= cmove; >++ hdl->sio.wsil = wsil; >++ } >++ if (hdl->sio.mode & SIO_REC) { >++ hdl->idelta -= cmove; >++ hdl->sio.rdrop = rdrop; >++ } >++ DPRINTFN(2, "xrun: corrected\n"); >++ DPRINTFN(2, "wsil = %d, rdrop = %d, odelta = %d, idelta = %d\n", >++ wsil, rdrop, hdl->odelta, hdl->idelta); >++ return 1; >++} >++ >++static int > +sio_oss_revents(struct sio_hdl *sh, struct pollfd *pfd) > +{ > + struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh; >++ audio_errinfo ei; > + int delta; > + int revents = pfd->revents; > + long long play_pos, rec_pos; >@@ -573,9 +594,21 @@ > + (pfd->revents & (POLLIN | POLLOUT)) == 0) > + return pfd->revents; > + >++ /* Hide xruns from clients */ >++ if (ioctl(hdl->fd, SNDCTL_DSP_GETERROR, &ei) < 0) { >++ DPERROR("sio_oss_revents: GETERROR"); >++ hdl->sio.eof = 1; >++ return POLLHUP; >++ } >++ if (ei.play_underruns > 0 || ei.rec_overruns > 0) { >++ if (!sio_oss_xrun(hdl)) >++ return POLLHUP; >++ return 0; >++ } >++ > + if (hdl->sio.mode & SIO_PLAY) { > + if (ioctl(hdl->fd, SNDCTL_DSP_CURRENT_OPTR, &optr) < 0) { >-+ DPERROR("sio_oss_revents: "); >++ DPERROR("sio_oss_revents: CURRENT_OPTR"); > + hdl->sio.eof = 1; > + return POLLHUP; > + } >@@ -589,7 +622,7 @@ > + } > + if (hdl->sio.mode & SIO_REC) { > + if (ioctl(hdl->fd, SNDCTL_DSP_CURRENT_IPTR, &iptr) < 0) { >-+ DPERROR("sio_oss_revents: "); >++ DPERROR("sio_oss_revents: CURRENT_IPTR"); > + hdl->sio.eof = 1; > + return POLLHUP; > + } >@@ -611,231 +644,4 @@ > + return revents; > +} > + >-+static void >-+sio_oss_fmt_to_swpar(int fmt, struct audio_swpar *ap) { >-+ switch(fmt) { >-+ case AFMT_S8: >-+ ap->le = 1; >-+ ap->sig = 1; >-+ ap->bits = 8; >-+ break; >-+ case AFMT_U8: >-+ ap->le = 1; >-+ ap->sig = 0; >-+ ap->bits = 8; >-+ break; >-+ case AFMT_S16_LE: >-+ ap->le = 1; >-+ ap->sig = 1; >-+ ap->bits = 16; >-+ break; >-+ case AFMT_S16_BE: >-+ ap->le = 0; >-+ ap->sig = 1; >-+ ap->bits = 16; >-+ break; >-+ case AFMT_U16_LE: >-+ ap->le = 1; >-+ ap->sig = 0; >-+ ap->bits = 16; >-+ break; >-+ case AFMT_U16_BE: >-+ ap->le = 0; >-+ ap->sig = 0; >-+ ap->bits = 16; >-+ break; >-+ case AFMT_S24_LE: >-+ ap->le = 1; >-+ ap->sig = 1; >-+ ap->bits = 24; >-+ break; >-+ case AFMT_S24_BE: >-+ ap->le = 0; >-+ ap->sig = 1; >-+ ap->bits = 24; >-+ break; >-+ case AFMT_U24_LE: >-+ ap->le = 1; >-+ ap->sig = 0; >-+ ap->bits = 24; >-+ break; >-+ case AFMT_U24_BE: >-+ ap->le = 0; >-+ ap->sig = 0; >-+ ap->bits = 24; >-+ break; >-+ case AFMT_S32_LE: >-+ ap->le = 1; >-+ ap->sig = 1; >-+ ap->bits = 32; >-+ break; >-+ case AFMT_S32_BE: >-+ ap->le = 0; >-+ ap->sig = 1; >-+ ap->bits = 32; >-+ break; >-+ case AFMT_U32_LE: >-+ ap->le = 1; >-+ ap->sig = 0; >-+ ap->bits = 32; >-+ break; >-+ case AFMT_U32_BE: >-+ ap->le = 0; >-+ ap->sig = 0; >-+ ap->bits = 32; >-+ break; >-+ } >-+} >-+ >-+static int >-+sio_oss_swpar_to_fmt(struct audio_swpar *ap) >-+{ >-+ unsigned int bits = ap->bits; >-+ unsigned int sig = ap->sig; >-+ unsigned int le = ap->le; >-+ >-+ switch(bits) { >-+ case 8: >-+ if (sig) >-+ return AFMT_S8; >-+ else >-+ return AFMT_U8; >-+ break; >-+ case 16: >-+ if (sig) >-+ if (le) >-+ return AFMT_S16_LE; >-+ else >-+ return AFMT_S16_BE; >-+ else >-+ if (le) >-+ return AFMT_U16_LE; >-+ else >-+ return AFMT_U16_BE; >-+ break; >-+ break; >-+ case 24: >-+ if (sig) >-+ if (le) >-+ return AFMT_S24_LE; >-+ else >-+ return AFMT_S24_BE; >-+ else >-+ if (le) >-+ return AFMT_U24_LE; >-+ else >-+ return AFMT_U24_BE; >-+ break; >-+ break; >-+ case 32: >-+ if (sig) >-+ if (le) >-+ return AFMT_S32_LE; >-+ else >-+ return AFMT_S32_BE; >-+ else >-+ if (le) >-+ return AFMT_U32_LE; >-+ else >-+ return AFMT_U32_BE; >-+ break; >-+ default: >-+ if (sig) >-+ if (SIO_LE_NATIVE) >-+ return AFMT_S16_LE; >-+ else >-+ return AFMT_S16_BE; >-+ else >-+ if (SIO_LE_NATIVE) >-+ return AFMT_U16_LE; >-+ else >-+ return AFMT_U16_BE; >-+ } >-+} >-+ >-+static int sio_oss_audio_getpar(struct sio_oss_hdl *hdl, struct audio_swpar *ap) >-+{ >-+ audio_buf_info bi; >-+ >-+ *ap = hdl->swpar; >-+ >-+ return 0; >-+} >-+ >-+static int sio_oss_audio_setpar(struct sio_oss_hdl *hdl, struct audio_swpar *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) { >-+ 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) { >-+ DPERROR("sio_oss_audio_setpar: SPEED"); >-+ return -1; >-+ } >-+ >-+ 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_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; >-+} >-+ > +#endif /* defined USE_OSS */ >diff --git a/audio/sndio/files/sndiod.in b/audio/sndio/files/sndiod.in >old mode 100644 >new mode 100755 >index 87d1087..2300f2b >--- a/audio/sndio/files/sndiod.in >+++ b/audio/sndio/files/sndiod.in >@@ -3,19 +3,10 @@ > # $FreeBSD$ > # > # PROVIDE: sndiod >-# REQUIRE: NETWORKING >+# REQUIRE: NETWORKING sysctl > # BEFORE: DAEMON > # KEYWORD: shutdown > >-# By default sndiod will use the audio device from >-# hw.snd.default_unit. You can override this by setting sndiod_flags. >-# >-# To connect to a remote sndiod use e.g. >-# sndiod_flags="-f snd@remotehost/0" >-# >-# To use /dev/dsp5 >-# sndiod_flags="-f rsnd/5" >- > . /etc/rc.subr > > name=sndiod >@@ -23,8 +14,9 @@ rcvar=sndiod_enable > > load_rc_config $name > >+: ${sndiod_dev="rsnd/$($SYSCTL -n hw.snd.default_unit)"} > : ${sndiod_enable="NO"} >-: ${sndiod_flags="-s default -m mon -s monitor"} >+: ${sndiod_flags="-f ${sndiod_dev} -c 0:7 -j off -s default -m mon -s monitor"} > > command="%%PREFIX%%/bin/sndiod" > >diff --git a/audio/sndio/pkg-message b/audio/sndio/pkg-message >index 7b4572d..de3663c 100644 >--- a/audio/sndio/pkg-message >+++ b/audio/sndio/pkg-message >@@ -1,7 +1,3 @@ >-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. >- > Enable the sndiod server with: > > sysrc sndiod_enable=YES >@@ -13,19 +9,12 @@ 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: >+Make sure you override sndiod_flags if this is not wanted. > >- export AUDIODEVICE=snd@remotehost/0 >+By default the rc.d script passes '-c 0:7 -j off' to sndiod, so that >+it uses all 8 virtual channels provided by OSS. If you override >+sndiod_flags consider keeping these options, so that multi-channel >+audio works as you'd expect. > > 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
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
tobik
:
maintainer-approval+
Actions:
View
|
Diff
Attachments on
bug 214210
:
176616
|
176617
|
176676
|
176678
|
176684