diff options
author | cpm <cpm@FreeBSD.org> | 2017-02-02 01:04:29 +0800 |
---|---|---|
committer | cpm <cpm@FreeBSD.org> | 2017-02-02 01:04:29 +0800 |
commit | c6b6ff9e23397e1677110c0b5683f1591fc3b45e (patch) | |
tree | 947ff89a2a851a65e8b53813d36706cc0072bd8f | |
parent | e43fdd42d7dfc383f928ecd947f9abc5bd76bcec (diff) | |
download | freebsd-ports-gnome-c6b6ff9e23397e1677110c0b5683f1591fc3b45e.tar.gz freebsd-ports-gnome-c6b6ff9e23397e1677110c0b5683f1591fc3b45e.tar.zst freebsd-ports-gnome-c6b6ff9e23397e1677110c0b5683f1591fc3b45e.zip |
audio/sndio: Various fixes
- Success in opening /dev/dsp* O_RDWR does not mean the device
supports play/recording. Add an extra check to see if the requested
mode is really supported.
- sndiod cannot currently be started in jails as root, because it
tries to setpriority(-20). Allow setpriority to fail and start the
daemon anyway.
- Fallback to /dev/dsp instead of /dev/dsp0 when using libsndio directly
without a running sndiod.
- Implement sio_setvol in the OSS backend for application level volume
control with just libsndio.
PR: 216571
Submitted by: Tobias Kortkamp <t@tobik.me> (maintainer)
-rw-r--r-- | audio/sndio/Makefile | 6 | ||||
-rw-r--r-- | audio/sndio/files/patch-libsndio_sio.c | 11 | ||||
-rw-r--r-- | audio/sndio/files/patch-libsndio_sio__oss.c | 123 | ||||
-rw-r--r-- | audio/sndio/pkg-message | 27 |
4 files changed, 140 insertions, 27 deletions
diff --git a/audio/sndio/Makefile b/audio/sndio/Makefile index e45e68cce4ab..f53c799e1c70 100644 --- a/audio/sndio/Makefile +++ b/audio/sndio/Makefile @@ -3,6 +3,7 @@ PORTNAME= sndio PORTVERSION= 1.2.0 +PORTREVISION= 1 CATEGORIES= audio MASTER_SITES= http://www.sndio.org/ @@ -24,6 +25,11 @@ GROUPS= _sndio # as is so not worth fixing MAKE_JOBS_UNSAFE= yes +post-patch: +# Make sure sndiod can be started inside jails as root + @${REINPLACE_CMD} 's|err(1, "setpriority")|warn("setpriority")|' \ + ${WRKSRC}/sndiod/sndiod.c + post-install: @${STRIP_CMD} \ ${STAGEDIR}${PREFIX}/lib/libsndio.so.6.1 \ diff --git a/audio/sndio/files/patch-libsndio_sio.c b/audio/sndio/files/patch-libsndio_sio.c new file mode 100644 index 000000000000..8cdac7f1b678 --- /dev/null +++ b/audio/sndio/files/patch-libsndio_sio.c @@ -0,0 +1,11 @@ +--- libsndio/sio.c.orig 2016-11-06 11:21:59 UTC ++++ libsndio/sio.c +@@ -65,7 +65,7 @@ sio_open(const char *str, unsigned int m + #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(SIO_DEVANY, mode, nbio); + #elif defined(USE_ALSA) + return _sio_alsa_open("rsnd/0", mode, nbio); + #else diff --git a/audio/sndio/files/patch-libsndio_sio__oss.c b/audio/sndio/files/patch-libsndio_sio__oss.c new file mode 100644 index 000000000000..51964ed64f80 --- /dev/null +++ b/audio/sndio/files/patch-libsndio_sio__oss.c @@ -0,0 +1,123 @@ +--- libsndio/sio_oss.c.orig 2016-11-06 11:21:59 UTC ++++ libsndio/sio_oss.c +@@ -108,6 +108,8 @@ static int sio_oss_xrun(struct sio_oss_h + 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 int sio_oss_setvol(struct sio_hdl *, unsigned int); ++static void sio_oss_getvol(struct sio_hdl *); + + static struct sio_ops sio_oss_ops = { + sio_oss_close, +@@ -121,8 +123,8 @@ static struct sio_ops sio_oss_ops = { + sio_oss_nfds, + sio_oss_pollfd, + sio_oss_revents, +- NULL, /* setvol */ +- NULL, /* getvol */ ++ sio_oss_setvol, ++ sio_oss_getvol, + }; + + /* +@@ -228,12 +230,10 @@ sio_oss_getcap(struct sio_hdl *sh, struc + } + + static int +-sio_oss_getfd(const char *str, unsigned int mode, int nbio) ++_sio_oss_getdev(const char *str, char *path, size_t len) + { + const char *p; +- char path[DEVPATH_MAX]; + unsigned int devnum; +- int fd, flags, val; + + p = _sndio_parsetype(str, "rsnd"); + if (p == NULL) { +@@ -253,7 +253,24 @@ sio_oss_getfd(const char *str, unsigned + DPRINTF("sio_oss_getfd: %s: number expected after '/'\n", str); + return -1; + } +- snprintf(path, sizeof(path), DEVPATH_PREFIX "%u", devnum); ++ snprintf(path, len, DEVPATH_PREFIX "%u", devnum); ++ return 0; ++} ++ ++static int ++sio_oss_getfd(const char *str, unsigned int mode, int nbio) ++{ ++ char path[DEVPATH_MAX]; ++ int fd, flags, val; ++ audio_buf_info bi; ++ ++ if (strcmp(str, SIO_DEVANY) == 0) { ++ /* Use /dev/dsp (the default device) directly */ ++ snprintf(path, sizeof(path), DEVPATH_PREFIX); ++ } else if (_sio_oss_getdev(str, path, sizeof(path)) < 0) { ++ return -1; ++ } ++ + if (mode == (SIO_PLAY | SIO_REC)) + flags = O_RDWR; + else +@@ -264,6 +281,19 @@ sio_oss_getfd(const char *str, unsigned + DPERROR(path); + return -1; + } ++ /* ++ * Check if the device supports playing/recording. ++ * Unfortunately, it's possible for devices to be opened RDWR ++ * even when they don't support playing/recording. ++ */ ++ if (mode & SIO_PLAY && ioctl(fd, SNDCTL_DSP_GETOSPACE, &bi) < 0) { ++ close(fd); ++ return -1; ++ } ++ if (mode & SIO_REC && ioctl(fd, SNDCTL_DSP_GETISPACE, &bi) < 0) { ++ close(fd); ++ return -1; ++ } + val = 1; + if (ioctl(fd, SNDCTL_DSP_LOW_WATER, &val) < 0) { + DPERROR("sio_oss_start: LOW_WATER"); +@@ -736,4 +766,40 @@ sio_oss_revents(struct sio_hdl *sh, stru + return revents; + } + ++static int ++sio_oss_setvol(struct sio_hdl *sh, unsigned int vol) ++{ ++ struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh; ++ int newvol; ++ ++ /* Scale to 0..100 */ ++ newvol = 1.0 * 100 * vol / SIO_MAXVOL; ++ newvol = newvol | (newvol << 8); ++ ++ if (ioctl(hdl->fd, SNDCTL_DSP_SETPLAYVOL, &newvol) < 0) { ++ DPERROR("sio_oss_setvol"); ++ hdl->sio.eof = 1; ++ return 0; ++ } ++ ++ return 1; ++} ++ ++static void ++sio_oss_getvol(struct sio_hdl *sh) ++{ ++ struct sio_oss_hdl *hdl = (struct sio_oss_hdl *)sh; ++ int vol; ++ ++ if (ioctl(hdl->fd, SNDCTL_DSP_GETPLAYVOL, &vol) < 0) { ++ DPERROR("sio_oss_getvol"); ++ hdl->sio.eof = 1; ++ return; ++ } ++ ++ /* Use left channel volume and scale to SIO_MAXVOL */ ++ vol = SIO_MAXVOL * 1.0 * (vol & 0x7f) / 100; ++ _sio_onvol_cb(&hdl->sio, vol); ++} ++ + #endif /* defined USE_OSS */ diff --git a/audio/sndio/pkg-message b/audio/sndio/pkg-message deleted file mode 100644 index de3663c39307..000000000000 --- a/audio/sndio/pkg-message +++ /dev/null @@ -1,27 +0,0 @@ -Enable the sndiod server with: - - sysrc sndiod_enable=YES - service sndiod start - -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. - -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 -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 -PulseAudio support but no direct sndio support. |