summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorratchov <ratchov@openbsd.org>2009-08-21 16:48:03 +0000
committerratchov <ratchov@openbsd.org>2009-08-21 16:48:03 +0000
commit8c73b7125fcd402a83a3cf3cbcfc0c78b3a5770f (patch)
treebb98de92ee3f920c7ea8083004a1d569adf3cef1
parentFix for PR6213, peers with 4-byte AS numbers were unable to connect to a (diff)
downloadwireguard-openbsd-8c73b7125fcd402a83a3cf3cbcfc0c78b3a5770f.tar.xz
wireguard-openbsd-8c73b7125fcd402a83a3cf3cbcfc0c78b3a5770f.zip
make aucat(1) expose a MIDI device to control server behaviour in
realtime. For now only the playback volume of individual streams can be changed/monitored. To each stream is assigned a MIDI channel; the volume is changed/monitored using the standard controller number 7.
-rw-r--r--lib/libsndio/mio.c6
-rw-r--r--lib/libsndio/mio_priv.h3
-rw-r--r--lib/libsndio/mio_thru.c33
-rw-r--r--lib/libsndio/sndio.728
-rw-r--r--usr.bin/aucat/abuf.c11
-rw-r--r--usr.bin/aucat/aproc.h11
-rw-r--r--usr.bin/aucat/aucat.118
-rw-r--r--usr.bin/aucat/dev.c8
-rw-r--r--usr.bin/aucat/midi.c241
-rw-r--r--usr.bin/aucat/midi.h7
-rw-r--r--usr.bin/aucat/sock.c18
-rw-r--r--usr.bin/aucat/sock.h3
12 files changed, 356 insertions, 31 deletions
diff --git a/lib/libsndio/mio.c b/lib/libsndio/mio.c
index 6bdb0a6ac2e..cbeeb5d6be6 100644
--- a/lib/libsndio/mio.c
+++ b/lib/libsndio/mio.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mio.c,v 1.6 2009/07/27 06:30:34 ratchov Exp $ */
+/* $OpenBSD: mio.c,v 1.7 2009/08/21 16:48:03 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -42,6 +42,7 @@ mio_open(const char *str, unsigned mode, int nbio)
{
static char prefix_midithru[] = "midithru";
static char prefix_rmidi[] = "rmidi";
+ static char prefix_aucat[] = "aucat";
struct mio_hdl *hdl;
struct stat sb;
char *sep, buf[4];
@@ -82,6 +83,9 @@ mio_open(const char *str, unsigned mode, int nbio)
if (len == (sizeof(prefix_midithru) - 1) &&
memcmp(str, prefix_midithru, len) == 0)
return mio_open_thru(sep + 1, mode, nbio);
+ if (len == (sizeof(prefix_aucat) - 1) &&
+ memcmp(str, prefix_aucat, len) == 0)
+ return mio_open_aucat(sep + 1, mode, nbio);
if (len == (sizeof(prefix_rmidi) - 1) &&
memcmp(str, prefix_rmidi, len) == 0)
return mio_open_rmidi(sep + 1, mode, nbio);
diff --git a/lib/libsndio/mio_priv.h b/lib/libsndio/mio_priv.h
index ec217394cc4..f5022dc6839 100644
--- a/lib/libsndio/mio_priv.h
+++ b/lib/libsndio/mio_priv.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mio_priv.h,v 1.3 2009/07/26 13:33:30 ratchov Exp $ */
+/* $OpenBSD: mio_priv.h,v 1.4 2009/08/21 16:48:03 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -59,6 +59,7 @@ struct mio_ops {
struct mio_hdl *mio_open_rmidi(const char *, unsigned, int);
struct mio_hdl *mio_open_thru(const char *, unsigned, int);
+struct mio_hdl *mio_open_aucat(const char *, unsigned, int);
void mio_create(struct mio_hdl *, struct mio_ops *, unsigned, int);
void mio_destroy(struct mio_hdl *);
diff --git a/lib/libsndio/mio_thru.c b/lib/libsndio/mio_thru.c
index 6f58ac7ee6a..a6d494d9377 100644
--- a/lib/libsndio/mio_thru.c
+++ b/lib/libsndio/mio_thru.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mio_thru.c,v 1.4 2009/07/26 12:40:45 ratchov Exp $ */
+/* $OpenBSD: mio_thru.c,v 1.5 2009/08/21 16:48:03 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -52,7 +52,7 @@ static struct mio_ops thru_ops = {
};
struct mio_hdl *
-mio_open_thru(const char *str, unsigned mode, int nbio)
+thru_open(const char *str, char *sock, unsigned mode, int nbio)
{
extern char *__progname;
struct amsg msg;
@@ -67,7 +67,7 @@ mio_open_thru(const char *str, unsigned mode, int nbio)
if (strchr(str, '/') != NULL)
return NULL;
snprintf(ca.sun_path, sizeof(ca.sun_path),
- "/tmp/aucat-%u/midithru%s", uid, str);
+ "/tmp/aucat-%u/%s%s", uid, sock, str);
ca.sun_family = AF_UNIX;
hdl = malloc(sizeof(struct thru_hdl));
@@ -81,7 +81,7 @@ mio_open_thru(const char *str, unsigned mode, int nbio)
while (connect(s, (struct sockaddr *)&ca, len) < 0) {
if (errno == EINTR)
continue;
- DPERROR("mio_open_thru: connect");
+ DPERROR("thru_open: connect");
goto bad_connect;
}
if (fcntl(s, F_SETFD, FD_CLOEXEC) < 0) {
@@ -100,14 +100,15 @@ mio_open_thru(const char *str, unsigned mode, int nbio)
msg.u.hello.proto |= AMSG_MIDIIN;
if (mode & MIO_OUT)
msg.u.hello.proto |= AMSG_MIDIOUT;
+ strlcpy(msg.u.hello.opt, "default", sizeof(msg.u.hello.opt));
strlcpy(msg.u.hello.who, __progname, sizeof(msg.u.hello.who));
n = write(s, &msg, sizeof(struct amsg));
if (n < 0) {
- DPERROR("mio_open_thru");
+ DPERROR("thru_open");
goto bad_connect;
}
if (n != sizeof(struct amsg)) {
- DPRINTF("mio_open_thru: short write\n");
+ DPRINTF("thru_open: short write\n");
goto bad_connect;
}
todo = sizeof(struct amsg);
@@ -115,22 +116,22 @@ mio_open_thru(const char *str, unsigned mode, int nbio)
while (todo > 0) {
n = read(s, data, todo);
if (n < 0) {
- DPERROR("mio_open_thru");
+ DPERROR("thru_open");
goto bad_connect;
}
if (n == 0) {
- DPRINTF("mio_open_thru: eof\n");
+ DPRINTF("thru_open: eof\n");
goto bad_connect;
}
todo -= n;
data += n;
}
if (msg.cmd != AMSG_ACK) {
- DPRINTF("mio_open_thru: proto error\n");
+ DPRINTF("thru_open: proto error\n");
goto bad_connect;
}
if (nbio && fcntl(hdl->fd, F_SETFL, O_NONBLOCK) < 0) {
- DPERROR("mio_open_thru: fcntl(NONBLOCK)");
+ DPERROR("thru_open: fcntl(NONBLOCK)");
goto bad_connect;
}
return (struct mio_hdl *)hdl;
@@ -142,6 +143,18 @@ mio_open_thru(const char *str, unsigned mode, int nbio)
return NULL;
}
+struct mio_hdl *
+mio_open_thru(const char *str, unsigned mode, int nbio)
+{
+ return thru_open(str, "midithru", mode, nbio);
+}
+
+struct mio_hdl *
+mio_open_aucat(const char *str, unsigned mode, int nbio)
+{
+ return thru_open(str, "softaudio", mode, nbio);
+}
+
static void
thru_close(struct mio_hdl *sh)
{
diff --git a/lib/libsndio/sndio.7 b/lib/libsndio/sndio.7
index e842cb468a3..3a7ac25ef63 100644
--- a/lib/libsndio/sndio.7
+++ b/lib/libsndio/sndio.7
@@ -1,4 +1,4 @@
-.\" $OpenBSD: sndio.7,v 1.1 2009/07/25 09:55:12 ratchov Exp $
+.\" $OpenBSD: sndio.7,v 1.2 2009/08/21 16:48:03 ratchov Exp $
.\"
.\" Copyright (c) 2007 Alexandre Ratchov <alex@caoua.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: July 25 2009 $
+.Dd $Mdocdate: August 21 2009 $
.Dt SNDIO 7
.Os
.Sh NAME
@@ -60,6 +60,11 @@ applications connected to the thru box (for instance a software sequencer
can send events to multiple software synthesizers).
There's no hardware involved: thru boxes are created by
.Xr midicat 1 .
+.Pp
+Additionally,
+.Xr aucat 1
+exposes a MIDI device used to control and monitor audio streams
+in real time using MIDI.
.Sh DEVICE NAMES
From the user's perspective every audio interface, MIDI port,
.Xr aucat 1
@@ -85,14 +90,17 @@ sockets and hardware
.Xr audio 4
devices.
Possible values for MIDI devices are
-.Pa midithru
-and
+.Pa midithru ,
.Pa rmidi ,
+and
+.Pa aucat
corresponding to
.Xr midicat 1
-software MIDI thru boxes and hardware
+software MIDI thru boxes, hardware
.Xr midi 4
-ports respectively.
+ports and
+.Xr aucat 1
+control through MIDI respectively.
.It Pa unit
For hardware audio or MIDI devices, this corresponds to
the character device minor number.
@@ -119,7 +127,7 @@ For example:
.It Pa sun:0
First hardware audio device.
.It Pa aucat:0
-Default device of the first
+Default audio device of the first
.Xr aucat 1
audio server.
.It Pa aucat:0.rear
@@ -132,7 +140,11 @@ device registered with
Hardware MIDI port number 5.
.It Pa midithru:0
First software MIDI thru box created with
-.Xr aucat 1 .
+.Xr midicat 1 .
+.It Pa aucat:0
+MIDI port controlling the first
+.Xr aucat 1
+audio server.
.El
.Sh ENVIRONMENT
.Bl -tag -width "AUDIODEVICEXXX" -compact
diff --git a/usr.bin/aucat/abuf.c b/usr.bin/aucat/abuf.c
index 6a9dab383ca..f989498816e 100644
--- a/usr.bin/aucat/abuf.c
+++ b/usr.bin/aucat/abuf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: abuf.c,v 1.13 2009/07/25 10:52:18 ratchov Exp $ */
+/* $OpenBSD: abuf.c,v 1.14 2009/08/21 16:48:03 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -105,8 +105,17 @@ abuf_del(struct abuf *buf)
buf->duplex->duplex = NULL;
#ifdef DEBUG
if (buf->rproc || buf->wproc || ABUF_ROK(buf)) {
+ /*
+ * XXX : we should call abort(), here.
+ * However, poll() doesn't seem to return POLLHUP,
+ * so the reader is never destroyed; instead it appears
+ * as blocked. Fix file_poll(), if fixable, and add
+ * a call to abord() here.
+ */
+#if 0
ABUF_DPRN(0, buf, "abuf_del: used = %u\n", buf->used);
abort();
+#endif
}
#endif
free(buf);
diff --git a/usr.bin/aucat/aproc.h b/usr.bin/aucat/aproc.h
index 43e3619688f..353fc593dc4 100644
--- a/usr.bin/aucat/aproc.h
+++ b/usr.bin/aucat/aproc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: aproc.h,v 1.18 2009/07/25 10:52:18 ratchov Exp $ */
+/* $OpenBSD: aproc.h,v 1.19 2009/08/21 16:48:03 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -166,6 +166,15 @@ struct aproc {
struct abuf *owner; /* current input stream */
struct timo timo; /* timout for throtteling */
} thru;
+ struct {
+#define CTL_NSLOT 8
+#define CTL_NAMEMAX 8
+ struct ctl_slot {
+ struct aproc *owner;
+ unsigned unit;
+ char name[CTL_NAMEMAX];
+ } slot[CTL_NSLOT];
+ } ctl;
} u;
};
diff --git a/usr.bin/aucat/aucat.1 b/usr.bin/aucat/aucat.1
index 091de15c042..ab428d71f8f 100644
--- a/usr.bin/aucat/aucat.1
+++ b/usr.bin/aucat/aucat.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: aucat.1,v 1.54 2009/07/25 08:44:27 ratchov Exp $
+.\" $OpenBSD: aucat.1,v 1.55 2009/08/21 16:48:03 ratchov Exp $
.\"
.\" Copyright (c) 2006 Alexandre Ratchov <alex@caoua.org>
.\"
@@ -14,7 +14,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: July 25 2009 $
+.Dd $Mdocdate: August 21 2009 $
.Dt AUCAT 1
.Os
.Sh NAME
@@ -350,6 +350,20 @@ For example:
$ aucat -b 3500 -l
$ sudo renice -n -20 -p `pgrep -x aucat`
.Ed
+.Sh MIDI CONTROL
+While running in server mode
+.Pq Fl l
+.Nm
+exposes a MIDI device with the same name as the default audio
+device.
+It allows MIDI hardware or software to be used to control
+the volume of played streams.
+To each stream is assigned a MIDI channel, and the volume
+is changed using the standard volume controller (number 7).
+Similarly, when the audio application changes its volume,
+the same MIDI controller message is sent out; it can be used
+for instance for monitoring or as feed-back for motorized
+faders.
.Sh LEGACY MODE
If neither
.Fl i
diff --git a/usr.bin/aucat/dev.c b/usr.bin/aucat/dev.c
index 3fde1b2905f..98b46668cf0 100644
--- a/usr.bin/aucat/dev.c
+++ b/usr.bin/aucat/dev.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dev.c,v 1.28 2009/08/19 05:54:15 ratchov Exp $ */
+/* $OpenBSD: dev.c,v 1.29 2009/08/21 16:48:03 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -291,6 +291,8 @@ dev_init(char *devpath,
}
dev_bufsz = (dopar) ? obufsz : ibufsz;
DPRINTF("dev_init: using %u fpb\n", dev_bufsz);
+ dev_midi = ctl_new("ctl");
+ dev_midi->refs++;
dev_start();
return 1;
}
@@ -305,6 +307,10 @@ dev_done(void)
struct file *f;
DPRINTF("dev_done: dev_mix = %p, dev_sub = %p\n", dev_mix, dev_sub);
+ dev_midi->refs--;
+ aproc_del(dev_midi);
+ dev_midi = NULL;
+
if (dev_mix) {
dev_mix->refs--;
dev_mix->u.mix.flags |= MIX_AUTOQUIT;
diff --git a/usr.bin/aucat/midi.c b/usr.bin/aucat/midi.c
index 58bfd6feaaa..cef251afa84 100644
--- a/usr.bin/aucat/midi.c
+++ b/usr.bin/aucat/midi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: midi.c,v 1.2 2009/08/19 05:54:15 ratchov Exp $ */
+/* $OpenBSD: midi.c,v 1.3 2009/08/21 16:48:03 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -29,9 +29,10 @@
#include <stdlib.h>
#include <string.h>
-#include "conf.h"
#include "abuf.h"
#include "aproc.h"
+#include "conf.h"
+#include "dev.h"
#include "midi.h"
/*
@@ -41,6 +42,32 @@
#define MIDITHRU_XFER 340
#define MIDITHRU_TIMO 100000
+/*
+ * masks to extract command and channel of status byte
+ */
+#define MIDI_CMDMASK 0xf0
+#define MIDI_CHANMASK 0x0f
+
+/*
+ * MIDI status bytes of voice messages
+ */
+#define MIDI_NOFF 0x80 /* note off */
+#define MIDI_NON 0x90 /* note on */
+#define MIDI_KAT 0xa0 /* key after touch */
+#define MIDI_CTL 0xb0 /* controller */
+#define MIDI_PC 0xc0 /* program change */
+#define MIDI_CAT 0xd0 /* channel after touch */
+#define MIDI_BEND 0xe0 /* pitch bend */
+
+/*
+ * MIDI controller numbers
+ */
+#define MIDI_CTLVOL 7 /* volume */
+#define MIDI_CTLPAN 11 /* pan */
+
+/*
+ * length of voice and common messages (status byte included)
+ */
unsigned voice_len[] = { 3, 3, 3, 3, 2, 2, 3 };
unsigned common_len[] = { 0, 2, 3, 2, 0, 0, 1, 1 };
@@ -266,3 +293,213 @@ thru_new(char *name)
return p;
}
+void
+ctl_sendmsg(struct aproc *p, struct abuf *ibuf, unsigned char *msg, unsigned len)
+{
+ unsigned ocount, itodo;
+ unsigned char *odata, *idata;
+ struct abuf *i, *inext;
+
+ for (i = LIST_FIRST(&p->obuflist); i != NULL; i = inext) {
+ inext = LIST_NEXT(i, oent);
+ if (i->duplex == ibuf)
+ continue;
+ itodo = len;
+ idata = msg;
+ while (itodo > 0) {
+ if (!ABUF_WOK(i)) {
+ DPRINTFN(2, "ctl_sendmsg: lost %u\n", i->used);
+ abuf_rdiscard(i, i->used);
+ }
+ odata = abuf_wgetblk(i, &ocount, 0);
+ if (ocount > itodo)
+ ocount = itodo;
+ DPRINTFN(2, "ctl_sendmsg: xfer %u\n", ocount);
+ memcpy(odata, idata, ocount);
+ abuf_wcommit(i, ocount);
+ itodo -= ocount;
+ idata += ocount;
+ }
+ (void)abuf_flush(i);
+ }
+}
+
+int
+ctl_slotnew(struct aproc *p, char *name, struct aproc *owner)
+{
+ char *s;
+ int index, i;
+ struct ctl_slot *slot;
+
+ DPRINTF("ctl_newslot: called by %s \"%s\"\n", owner->name, name);
+ for (index = 0, slot = p->u.ctl.slot; ; index++, slot++) {
+ if (index == CTL_NSLOT)
+ return -1;
+ if (slot->owner == NULL)
+ break;
+ }
+ for (i = 0, s = name; ; s++) {
+ if (i == CTL_NAMEMAX - 1 || *s == '\0') {
+ break;
+ } else if (*s >= 'A' && *s <= 'Z') {
+ slot->name[i++] = *s + 'a' - 'A';
+ } else if (*s >= 'a' || *s <= 'z')
+ slot->name[i++] = *s;
+ }
+ if (i == 0)
+ strlcpy(slot->name, "noname", CTL_NAMEMAX);
+ else
+ slot->name[i] = '\0';
+ slot->owner = owner;
+ slot->unit = index;
+ DPRINTFN(1, "ctl_newslot: %s%u\n", slot->name, slot->unit);
+ return index;
+}
+
+void
+ctl_slotdel(struct aproc *p, int index)
+{
+ p->u.ctl.slot[index].owner = NULL;
+}
+
+void
+ctl_slotvol(struct aproc *p, int slot, unsigned vol)
+{
+ unsigned char msg[3];
+
+ DPRINTFN(1, "ctl_slotvol: [%u] -> %u\n", slot, vol);
+ msg[0] = MIDI_CTL | slot;
+ msg[1] = MIDI_CTLVOL;
+ msg[2] = vol;
+ ctl_sendmsg(p, NULL, msg, 3);
+}
+
+void
+ctl_ev(struct aproc *p, struct abuf *ibuf)
+{
+ unsigned i;
+ unsigned chan;
+ struct aproc *owner;
+
+#ifdef DEBUG
+ if (debug_level > 0) {
+ fprintf(stderr, "ctl_ev:");
+ for (i = 0; i < ibuf->mlen; i++)
+ fprintf(stderr, " %02x", ibuf->mdata[i]);
+ fprintf(stderr, "\n");
+ }
+#endif
+ if ((ibuf->mdata[0] & MIDI_CMDMASK) == MIDI_CTL &&
+ ibuf->mdata[1] == MIDI_CTLVOL) {
+ chan = ibuf->mdata[0] & MIDI_CHANMASK;
+ if (chan >= CTL_NSLOT)
+ return;
+ owner = p->u.ctl.slot[chan].owner;
+ if (owner == NULL || LIST_EMPTY(&owner->obuflist))
+ return;
+ dev_setvol(
+ LIST_FIRST(&owner->obuflist),
+ MIDI_TO_ADATA(ibuf->mdata[2]));
+ ctl_sendmsg(p, ibuf, ibuf->mdata, ibuf->mlen);
+ }
+}
+
+int
+ctl_in(struct aproc *p, struct abuf *ibuf)
+{
+ unsigned char *idata;
+ unsigned c, i, icount;
+
+ if (!ABUF_ROK(ibuf))
+ return 0;
+ idata = abuf_rgetblk(ibuf, &icount, 0);
+ for (i = 0; i < icount; i++) {
+ c = *idata++;
+ if (c >= 0xf0) {
+ /* clock and common events not used yet */
+ } else if (c >= 0x80) {
+ ibuf->mdata[0] = c;
+ ibuf->mlen = voice_len[(c >> 4) & 7];
+ ibuf->mstatus = c;
+ ibuf->mindex = 1;
+ } else if (ibuf->mstatus) {
+ if (ibuf->mindex == 0)
+ ibuf->mdata[ibuf->mindex++] = ibuf->mstatus;
+ ibuf->mdata[ibuf->mindex++] = c;
+ if (ibuf->mindex == ibuf->mlen) {
+ ctl_ev(p, ibuf);
+ ibuf->mindex = 0;
+ }
+ }
+ }
+ abuf_rdiscard(ibuf, icount);
+ return 1;
+}
+
+int
+ctl_out(struct aproc *p, struct abuf *obuf)
+{
+ return 0;
+}
+
+void
+ctl_eof(struct aproc *p, struct abuf *ibuf)
+{
+ DPRINTF("ctl_eof: %s: eof\n", p->name);
+}
+
+void
+ctl_hup(struct aproc *p, struct abuf *obuf)
+{
+ DPRINTF("ctl_hup: %s: detached\n", p->name);
+}
+
+void
+ctl_newin(struct aproc *p, struct abuf *ibuf)
+{
+ ibuf->mused = 0;
+ ibuf->mlen = 0;
+ ibuf->mindex = 0;
+ ibuf->mstatus = 0;
+}
+
+void
+ctl_done(struct aproc *p)
+{
+ unsigned i;
+ struct ctl_slot *s;
+
+ for (i = 0, s = p->u.ctl.slot; i < CTL_NSLOT; i++, s++) {
+ if (s->owner)
+ DPRINTF("ctl_done: %s%u not freed\n", s->name, s->unit);
+ }
+}
+
+struct aproc_ops ctl_ops = {
+ "ctl",
+ ctl_in,
+ ctl_out,
+ ctl_eof,
+ ctl_hup,
+ ctl_newin,
+ NULL, /* newout */
+ NULL, /* ipos */
+ NULL, /* opos */
+ ctl_done
+};
+
+struct aproc *
+ctl_new(char *name)
+{
+ struct aproc *p;
+ unsigned i;
+
+ p = aproc_new(&ctl_ops, name);
+ for (i = 0; i < CTL_NSLOT; i++) {
+ p->u.ctl.slot[i].unit = i;
+ p->u.ctl.slot[i].owner = NULL;
+ strlcpy(p->u.ctl.slot[i].name, "unknown", CTL_NAMEMAX);
+ }
+ return p;
+}
+
diff --git a/usr.bin/aucat/midi.h b/usr.bin/aucat/midi.h
index 597482dd02b..d48fbb2f3b6 100644
--- a/usr.bin/aucat/midi.h
+++ b/usr.bin/aucat/midi.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: midi.h,v 1.1 2009/07/25 08:44:27 ratchov Exp $ */
+/* $OpenBSD: midi.h,v 1.2 2009/08/21 16:48:03 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -18,7 +18,10 @@
#define MIDI_H
struct aproc *thru_new(char *);
+struct aproc *ctl_new(char *);
-extern struct aproc *thrubox;
+int ctl_slotnew(struct aproc *, char *, struct aproc *);
+void ctl_slotdel(struct aproc *, int);
+void ctl_slotvol(struct aproc *, int, unsigned);
#endif /* !defined(MIDI_H) */
diff --git a/usr.bin/aucat/sock.c b/usr.bin/aucat/sock.c
index 79f0aa092ca..8e1cd9f551e 100644
--- a/usr.bin/aucat/sock.c
+++ b/usr.bin/aucat/sock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sock.c,v 1.23 2009/08/19 05:54:15 ratchov Exp $ */
+/* $OpenBSD: sock.c,v 1.24 2009/08/21 16:48:03 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -63,6 +63,8 @@ rsock_done(struct aproc *p)
sock_reset(f);
f->pipe.file.rproc = NULL;
if (f->pipe.file.wproc) {
+ if (dev_midi && f->slot >= 0)
+ ctl_slotdel(dev_midi, f->slot);
aproc_del(f->pipe.file.wproc);
file_del(&f->pipe.file);
}
@@ -175,6 +177,8 @@ wsock_done(struct aproc *p)
sock_reset(f);
f->pipe.file.wproc = NULL;
if (f->pipe.file.rproc) {
+ if (dev_midi && f->slot >= 0)
+ ctl_slotdel(dev_midi, f->slot);
aproc_del(f->pipe.file.rproc);
file_del(&f->pipe.file);
}
@@ -298,6 +302,7 @@ sock_new(struct fileops *ops, int fd)
f->delta = 0;
f->tickpending = 0;
f->vol = ADATA_UNIT;
+ f->slot = -1;
wproc = aproc_new(&wsock_ops, f->pipe.file.name);
wproc->u.io.file = &f->pipe.file;
@@ -772,6 +777,15 @@ sock_hello(struct sock *f)
}
f->mode |= AMSG_REC;
}
+ if (dev_midi) {
+ f->slot = ctl_slotnew(dev_midi, p->who, f->pipe.file.rproc);
+ if (f->slot < 0) {
+ DPRINTF("sock_hello: out of mixer slots\n");
+ return 0;
+ }
+ if (f->mode & AMSG_PLAY)
+ ctl_slotvol(dev_midi, f->slot, MIDI_MAXCTL);
+ }
f->pstate = SOCK_INIT;
return 1;
}
@@ -913,6 +927,8 @@ sock_execmsg(struct sock *f)
}
DPRINTF("sock_execmsg: SETVOL %u\n", m->u.vol.ctl);
sock_setvol(f, MIDI_TO_ADATA(m->u.vol.ctl));
+ if (dev_midi && f->slot >= 0)
+ ctl_slotvol(dev_midi, f->slot, m->u.vol.ctl);
f->rtodo = sizeof(struct amsg);
f->rstate = SOCK_RMSG;
break;
diff --git a/usr.bin/aucat/sock.h b/usr.bin/aucat/sock.h
index d0eaeda1986..517264f3aee 100644
--- a/usr.bin/aucat/sock.h
+++ b/usr.bin/aucat/sock.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sock.h,v 1.8 2009/07/25 10:52:19 ratchov Exp $ */
+/* $OpenBSD: sock.h,v 1.9 2009/08/21 16:48:03 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -55,6 +55,7 @@ struct sock {
unsigned round; /* block size */
unsigned xrun; /* one of AMSG_IGNORE, ... */
int vol; /* requested volume */
+ int slot; /* mixer ctl slot number */
struct opt *opt; /* "subdevice" definition */
};