From 5324c19a9cdbfe32c8cd7f4ec3557d39506c9cf6 Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Thu, 30 Apr 2020 16:20:09 +0200 Subject: [PATCH 1/8] sndioctl.1 fixes, from schwarze@ --- sndioctl/sndioctl.1 | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/sndioctl/sndioctl.1 b/sndioctl/sndioctl.1 index f8645ba..68c82ce 100644 --- a/sndioctl/sndioctl.1 +++ b/sndioctl/sndioctl.1 @@ -100,20 +100,22 @@ If .Qq \&! is used instead of a number, then the switch is toggled. .Sh EXAMPLES -The following will set all -.Ar output -channels -.Ar level -control to zero: +Increase the +.Cm level +control affecting all +.Cm output +channels by 10% of the maximum: .Pp -.Dl $ sndioctl output.level=0 +.Dl $ sndioctl output.level=+0.1 .Pp -The following set all -.Ar output -channels -.Ar mute +Mute all output channels: +.Pp +.Dl $ sndioctl output.mute=1 +.Pp +Toggle the above +.Cm mute control: .Pp -.Dl $ sndioctl output.mute=0 +.Dl $ sndioctl output.mute=! .Sh SEE ALSO .Xr sioctl_open 3 From d785baf4f3961936a8396b8dda5661fdfa2989ea Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Thu, 30 Apr 2020 16:22:29 +0200 Subject: [PATCH 2/8] sndioctl: Display numbers with 3 decimal places, from schwarze@ --- sndioctl/sndioctl.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/sndioctl/sndioctl.c b/sndioctl/sndioctl.c index a800c90..eb961bf 100644 --- a/sndioctl/sndioctl.c +++ b/sndioctl/sndioctl.c @@ -374,7 +374,14 @@ print_val(struct info *p, int mono) switch (p->desc.type) { case SIOCTL_NUM: case SIOCTL_SW: - printf("%.2g", p->curval / (float)p->desc.maxval); + if (p->desc.maxval == 1) + printf("%d", p->curval); + else + /* + * For now, maxval is always 127 or 255, + * so three decimals is always ideal. + */ + printf("%.3f", p->curval / (float)p->desc.maxval); break; case SIOCTL_VEC: case SIOCTL_LIST: @@ -389,7 +396,11 @@ print_val(struct info *p, int mono) if (more) printf(","); print_node(&e->desc.node1, mono); - printf(":%.2g", e->curval / (float)e->desc.maxval); + if (e->desc.maxval == 1) + printf(":%d", e->curval); + else + printf(":%.3f", + e->curval / (float)e->desc.maxval); more = 1; } } From 5736faa146b239a4b8c53e57170f8280366aa12d Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Thu, 30 Apr 2020 16:27:32 +0200 Subject: [PATCH 3/8] Get a reference to the device when "snd/N" MIDI ports are opened As the master output level control is not in software any longer the device needs to opened for adjustments to work. --- sndiod/midi.c | 19 +++++++++++++++++++ sndiod/midi.h | 1 + sndiod/sock.c | 9 +++++++++ 3 files changed, 29 insertions(+) diff --git a/sndiod/midi.c b/sndiod/midi.c index 7c91ec9..643d888 100644 --- a/sndiod/midi.c +++ b/sndiod/midi.c @@ -190,6 +190,25 @@ midi_tag(struct midi *ep, unsigned int tag) t->txmask |= ep->self; } +/* + * return the list of tags + */ +unsigned int +midi_tags(struct midi *ep) +{ + int i; + struct midithru *t; + unsigned int tags; + + tags = 0; + for (i = 0; i < MIDITHRU_NMAX; i++) { + t = midithru + i; + if ((t->txmask | t->rxmask) & ep->self) + tags |= 1 << i; + } + return tags; +} + /* * broadcast the given message to other endpoints */ diff --git a/sndiod/midi.h b/sndiod/midi.h index e2ce168..cff3576 100644 --- a/sndiod/midi.h +++ b/sndiod/midi.h @@ -110,6 +110,7 @@ void midi_out(struct midi *, unsigned char *, int); void midi_send(struct midi *, unsigned char *, int); void midi_fill(struct midi *); void midi_tag(struct midi *, unsigned int); +unsigned int midi_tags(struct midi *); void midi_link(struct midi *, struct midi *); void port_log(struct port *); diff --git a/sndiod/sock.c b/sndiod/sock.c index 6eb2400..28c75b5 100644 --- a/sndiod/sock.c +++ b/sndiod/sock.c @@ -130,7 +130,9 @@ sock_log(struct sock *f) void sock_close(struct sock *f) { + struct dev *d; struct sock **pf; + unsigned int tags, i; for (pf = &sock_list; *pf != f; pf = &(*pf)->next) { #ifdef DEBUG @@ -155,6 +157,11 @@ sock_close(struct sock *f) f->slot = NULL; } if (f->midi) { + tags = midi_tags(f->midi); + for (i = 0; i < DEV_NMAX; i++) { + if ((tags & (1 << i)) && (d = dev_bynum(i)) != NULL) + dev_unref(d); + } midi_del(f->midi); f->midi = NULL; } @@ -861,6 +868,8 @@ sock_hello(struct sock *f) d = dev_bynum(p->devnum); if (d == NULL) return 0; + if (!dev_ref(d)) + return 0; midi_tag(f->midi, p->devnum); } else if (p->devnum < 32) { midi_tag(f->midi, p->devnum); From 5750e312dbfabed8574955f81621a9ad6b1f0b28 Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Thu, 30 Apr 2020 16:33:08 +0200 Subject: [PATCH 4/8] sndiod: Record if a client belongs to a session --- sndiod/sock.c | 5 +++-- sndiod/sock.h | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/sndiod/sock.c b/sndiod/sock.c index 28c75b5..72a1ee5 100644 --- a/sndiod/sock.c +++ b/sndiod/sock.c @@ -151,7 +151,7 @@ sock_close(struct sock *f) } #endif if (f->pstate > SOCK_AUTH) - sock_sesrefs--; + sock_sesrefs -= f->sesrefs; if (f->slot) { slot_del(f->slot); f->slot = NULL; @@ -792,11 +792,12 @@ sock_auth(struct sock *f) if (sock_sesrefs == 0) { /* start a new session */ memcpy(sock_sescookie, p->cookie, AMSG_COOKIELEN); + f->sesrefs = 1; } else if (memcmp(sock_sescookie, p->cookie, AMSG_COOKIELEN) != 0) { /* another session is active, drop connection */ return 0; } - sock_sesrefs++; + sock_sesrefs += f->sesrefs; f->pstate = SOCK_HELLO; return 1; } diff --git a/sndiod/sock.h b/sndiod/sock.h index 41f0916..9926890 100644 --- a/sndiod/sock.h +++ b/sndiod/sock.h @@ -64,6 +64,7 @@ struct sock { #define SOCK_CTLVAL 2 /* send value changes */ unsigned int ctlops; /* bitmap of above */ int ctlsyncpending; /* CTLSYNC waiting to be transmitted */ + unsigned int sesrefs; /* 1 if socket belongs to a session */ }; struct sock *sock_new(int fd); From 8d24dd3ef82003b53d105e7e51a1b89c280e0cc2 Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Thu, 30 Apr 2020 17:25:22 +0200 Subject: [PATCH 5/8] sioctl_sun.c: If no "xxx.mute" control is found, try "xxx_mute" --- libsndio/sioctl_sun.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libsndio/sioctl_sun.c b/libsndio/sioctl_sun.c index 88a80c5..45267d7 100644 --- a/libsndio/sioctl_sun.c +++ b/libsndio/sioctl_sun.c @@ -84,14 +84,24 @@ static int initmute(struct sioctl_sun_hdl *hdl, struct mixer_devinfo *info) { struct mixer_devinfo mi; + char name[MAX_AUDIO_DEV_LEN]; - mi.index = info->next; for (mi.index = info->next; mi.index != -1; mi.index = mi.next) { if (ioctl(hdl->fd, AUDIO_MIXER_DEVINFO, &mi) < 0) break; if (strcmp(mi.label.name, AudioNmute) == 0) return mi.index; } + + /* try "_mute" suffix */ + snprintf(name, sizeof(name), "%s_mute", info->label.name); + for (mi.index = 0; ; mi.index++) { + if (ioctl(hdl->fd, AUDIO_MIXER_DEVINFO, &mi) < 0) + break; + if (info->mixer_class == mi.mixer_class && + strcmp(mi.label.name, name) == 0) + return mi.index; + } return -1; } From 7433055e88f18bb2ffb8d68a472a6f38703bed04 Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Thu, 30 Apr 2020 17:41:37 +0200 Subject: [PATCH 6/8] Use hardcoded rsnd/0 as openbsd default (hardware) device --- libsndio/sio.c | 2 +- libsndio/sio_sun.c | 12 ++++-------- libsndio/sioctl.c | 2 +- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/libsndio/sio.c b/libsndio/sio.c index 4b25930..0195f70 100644 --- a/libsndio/sio.c +++ b/libsndio/sio.c @@ -62,7 +62,7 @@ sio_open(const char *str, unsigned int mode, int nbio) if (hdl != NULL) return hdl; #if defined(USE_SUN) - return _sio_sun_open("rsnd/default", mode, nbio); + return _sio_sun_open("rsnd/0", mode, nbio); #elif defined(USE_OSS) return _sio_oss_open("rsnd/default", mode, nbio); #elif defined(USE_ALSA) diff --git a/libsndio/sio_sun.c b/libsndio/sio_sun.c index f6040b0..bc4dab8 100644 --- a/libsndio/sio_sun.c +++ b/libsndio/sio_sun.c @@ -290,14 +290,10 @@ sio_sun_getfd(const char *str, unsigned int mode, int nbio) DPRINTF("sio_sun_getfd: %s: '/' expected\n", str); return -1; } - if (strcmp(p, "default") == 0) { - devnum = 0; - } else { - p = _sndio_parsenum(p, &devnum, 255); - if (p == NULL || *p != '\0') { - DPRINTF("sio_sun_getfd: %s: number expected after '/'\n", str); - return -1; - } + p = _sndio_parsenum(p, &devnum, 255); + if (p == NULL || *p != '\0') { + DPRINTF("sio_sun_getfd: %s: number expected after '/'\n", str); + return -1; } snprintf(path, sizeof(path), DEVPATH_PREFIX "%u", devnum); if (mode == (SIO_PLAY | SIO_REC)) diff --git a/libsndio/sioctl.c b/libsndio/sioctl.c index e558404..2ecc1e8 100644 --- a/libsndio/sioctl.c +++ b/libsndio/sioctl.c @@ -45,7 +45,7 @@ sioctl_open(const char *str, unsigned int mode, int nbio) if (hdl != NULL) return hdl; #if defined(USE_SUN_MIXER) - return _sioctl_sun_open("rsnd/default", mode, nbio); + return _sioctl_sun_open("rsnd/0", mode, nbio); #else return NULL; #endif From f330fa3d4ad234fdcc9c42ea48cc1ebd1472dc77 Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Thu, 30 Apr 2020 19:04:30 +0200 Subject: [PATCH 7/8] If no -f options are used, expose first 4 midi(4) devices to sndiod clients A single default device could be set at ./configure time with the --default-dev option --- configure | 11 +++++++++++ sndiod/sndiod.8 | 8 ++++++++ sndiod/sndiod.c | 35 +++++++++++++++++++++++------------ 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/configure b/configure index fc0dcab..76b7596 100755 --- a/configure +++ b/configure @@ -24,6 +24,7 @@ Usage: configure [options] --disable-umidi disable usb-midi backend --with-libbsd use the libbsd rather than bsd-compat/* --without-libbsd don't use libbsd +--default-dev=DEV set default device [$dev] END } @@ -49,6 +50,7 @@ unset includedir # path where to install header file unset libdir # path where to install library unset defs # no extra #defines unset ldadd # no extra libraries (-l options) +unset dev # # guess OS-specific parameters @@ -170,6 +172,9 @@ for i; do --without-libbsd) libbsd=no shift;; + --default-dev=*) + dev="${i#--default-dev=}" + shift;; CC=*|CFLAGS=*|LDFLAGS=*) vars="$vars$i$nl" shift;; @@ -241,6 +246,11 @@ if [ $libbsd = yes ]; then ldadd="$ldadd -lbsd" fi +if [ -n "$dev" ]; then + defs="$defs -DDEFAULT_DEV=\\\"$dev\\\"" +fi + + for f in Makefile aucat/Makefile midicat/Makefile sndiod/Makefile \ libsndio/Makefile \ sndioctl/Makefile \ @@ -262,6 +272,7 @@ do -e "s:@vars@:${vars}:" \ -e "s:@precision@:$precision:" \ -e "s:@user@:$user:" \ + -e "s:@devs@:$devs:" \ < $f.in > $f done diff --git a/sndiod/sndiod.8 b/sndiod/sndiod.8 index 81f868d..40b9ef2 100644 --- a/sndiod/sndiod.8 +++ b/sndiod/sndiod.8 @@ -208,6 +208,14 @@ Sub-devices that are applied after will be attached to this device. Device mode and parameters are determined from sub-devices attached to it. +If no +.Fl f +option is used, +.Nm +will use +.Pa rsnd/0 , rsnd/1 , +.No ... , +.Pa rsnd/3 . .It Fl j Ar flag Control whether program channels are joined or expanded if the number of channels requested by a program is not equal diff --git a/sndiod/sndiod.c b/sndiod/sndiod.c index cacf8e3..f427be8 100644 --- a/sndiod/sndiod.c +++ b/sndiod/sndiod.c @@ -78,13 +78,6 @@ #define DEFAULT_BUFSZ 7680 #endif -/* - * default device in server mode - */ -#ifndef DEFAULT_DEV -#define DEFAULT_DEV "rsnd/default" -#endif - void sigint(int); void sighup(int); void opt_ch(int *, int *); @@ -111,6 +104,18 @@ char usagestr[] = "usage: sndiod [-d] [-a flag] [-b nframes] " "[-Q port] [-q port] [-r rate] [-s name] [-t mode] [-U unit]\n\t" "[-v volume] [-w flag] [-z nframes]\n"; +/* + * default audio devices + */ +static char *default_devs[] = { +#ifdef DEFAULT_DEV + DEFAULT_DEV, +#else + "rsnd/0", "rsnd/1", "rsnd/2", "rsnd/3", +#endif + NULL +}; + /* * default MIDI ports */ @@ -361,7 +366,7 @@ mkopt(char *path, struct dev *d, int main(int argc, char **argv) { - int c, i, background, unit; + int c, i, background, unit, devindex; int pmin, pmax, rmin, rmax; char base[SOCKPATH_MAX], path[SOCKPATH_MAX]; unsigned int mode, dup, mmc, vol; @@ -399,6 +404,7 @@ main(int argc, char **argv) aparams_init(&par); mode = MODE_PLAY | MODE_REC; tcpaddr_list = NULL; + devindex = 0; while ((c = getopt(argc, argv, "a:b:c:C:de:F:f:j:L:m:Q:q:r:s:t:U:v:w:x:z:")) != -1) { @@ -448,8 +454,8 @@ main(int argc, char **argv) break; case 's': if ((d = dev_list) == NULL) { - d = mkdev(DEFAULT_DEV, &par, 0, bufsz, round, - rate, hold, autovol); + d = mkdev(default_devs[devindex++], &par, 0, + bufsz, round, rate, hold, autovol); } if (mkopt(optarg, d, pmin, pmax, rmin, rmax, mode, vol, mmc, dup) == NULL) @@ -482,6 +488,7 @@ main(int argc, char **argv) case 'f': mkdev(optarg, &par, 0, bufsz, round, rate, hold, autovol); + devindex = -1; break; case 'F': if (dev_list == NULL) @@ -503,8 +510,12 @@ main(int argc, char **argv) for (i = 0; default_ports[i] != NULL; i++) mkport(default_ports[i], 0); } - if (dev_list == NULL) - mkdev(DEFAULT_DEV, &par, 0, bufsz, round, rate, hold, autovol); + if (devindex != -1) { + for (i = devindex; default_devs[i] != NULL; i++) { + mkdev(default_devs[i], &par, 0, + bufsz, round, rate, 0, autovol); + } + } for (d = dev_list; d != NULL; d = d->next) { if (opt_byname(d, "default")) continue; From a35ae59831ce806481557a282315fb1ed648fce1 Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Sat, 2 May 2020 15:28:08 +0200 Subject: [PATCH 8/8] configure: quote device name of --default-dev argument This remove the need for the quotes in the configure script argument making its invocation simpler --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index 76b7596..4b1facf 100755 --- a/configure +++ b/configure @@ -247,7 +247,7 @@ if [ $libbsd = yes ]; then fi if [ -n "$dev" ]; then - defs="$defs -DDEFAULT_DEV=\\\"$dev\\\"" + defs="$defs -DDEFAULT_DEV='\"$dev\"'" fi