summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexandre Ratchov <ratchov@cvs.openbsd.org>2011-06-27 07:17:45 +0000
committerAlexandre Ratchov <ratchov@cvs.openbsd.org>2011-06-27 07:17:45 +0000
commit1f581fa2caf2cd2dabe56f18b2c4349672e8dc90 (patch)
tree9f60e09976771a0a2386cad2e38c4ac8eda6c42a
parent685f9a3c03f78a2aa869a5b1b1be78f891d74917 (diff)
expose audio client names through sysex messages, this way any
midi client could determine which volume knob corresponds to which client. Such sysex messages are ignored by hardware or software that don't understand them
-rw-r--r--usr.bin/aucat/midi.c57
-rw-r--r--usr.bin/aucat/sysex.h24
2 files changed, 79 insertions, 2 deletions
diff --git a/usr.bin/aucat/midi.c b/usr.bin/aucat/midi.c
index c3175263f6d..d5135571294 100644
--- a/usr.bin/aucat/midi.c
+++ b/usr.bin/aucat/midi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: midi.c,v 1.34 2011/06/02 18:50:39 ratchov Exp $ */
+/* $OpenBSD: midi.c,v 1.35 2011/06/27 07:17:44 ratchov Exp $ */
/*
* Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
*
@@ -538,6 +538,26 @@ ctl_full(struct aproc *p)
}
void
+ctl_msg_info(struct aproc *p, int slot, char *msg)
+{
+ struct ctl_slot *s;
+ struct sysex *x = (struct sysex *)msg;
+
+ s = p->u.ctl.slot + slot;
+ memset(x, 0, sizeof(struct sysex));
+ x->start = SYSEX_START;
+ x->type = SYSEX_TYPE_EDU;
+ x->id0 = SYSEX_AUCAT;
+ x->id1 = SYSEX_AUCAT_MIXINFO;
+ if (*s->name != '\0') {
+ snprintf(x->u.mixinfo.name,
+ SYSEX_NAMELEN, "%s%u", s->name, s->unit);
+ }
+ x->u.mixinfo.chan = slot;
+ x->u.mixinfo.end = SYSEX_END;
+}
+
+void
ctl_msg_vol(struct aproc *p, int slot, char *msg)
{
struct ctl_slot *s;
@@ -548,6 +568,30 @@ ctl_msg_vol(struct aproc *p, int slot, char *msg)
msg[2] = s->vol;
}
+void
+ctl_dump(struct aproc *p, struct abuf *obuf)
+{
+ unsigned i;
+ unsigned char msg[sizeof(struct sysex)];
+ struct ctl_slot *s;
+
+ for (i = 0, s = p->u.ctl.slot; i < CTL_NSLOT; i++, s++) {
+ ctl_msg_info(p, i, msg);
+ ctl_copymsg(obuf, msg, SYSEX_SIZE(mixinfo));
+ ctl_msg_vol(p, i, msg);
+ ctl_copymsg(obuf, msg, 3);
+ }
+ msg[0] = SYSEX_START;
+ msg[1] = SYSEX_TYPE_EDU;
+ msg[2] = 0;
+ msg[3] = SYSEX_AUCAT;
+ msg[4] = SYSEX_AUCAT_DUMPEND;
+ msg[5] = SYSEX_END;
+ ctl_copymsg(obuf, msg, 6);
+ dbg_puts("end dump\n");
+ abuf_flush(obuf);
+}
+
/*
* find the best matching free slot index (ie midi channel).
* return -1, if there are no free slots anymore
@@ -765,6 +809,8 @@ ctl_slotnew(struct aproc *p, char *who, struct ctl_ops *ops, void *arg, int tr)
s->arg = arg;
s->tstate = tr ? CTL_STOP : CTL_OFF;
s->ops->vol(s->arg, s->vol);
+ ctl_msg_info(p, idx, msg);
+ ctl_sendmsg(p, NULL, msg, SYSEX_SIZE(mixinfo));
ctl_msg_vol(p, idx, msg);
ctl_sendmsg(p, NULL, msg, 3);
return idx;
@@ -1100,6 +1146,15 @@ ctl_ev(struct aproc *p, struct abuf *ibuf)
break;
}
break;
+ case SYSEX_TYPE_EDU:
+ if (x->id0 != SYSEX_AUCAT || x->id1 != SYSEX_AUCAT_DUMPREQ)
+ return;
+ if (len != SYSEX_SIZE(dumpreq))
+ return;
+ dbg_puts("dump request\n");
+ if (ibuf->duplex)
+ ctl_dump(p, ibuf->duplex);
+ break;
}
}
diff --git a/usr.bin/aucat/sysex.h b/usr.bin/aucat/sysex.h
index 1ec60054b63..ea32558d690 100644
--- a/usr.bin/aucat/sysex.h
+++ b/usr.bin/aucat/sysex.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sysex.h,v 1.1 2011/05/09 18:03:08 ratchov Exp $ */
+/* $OpenBSD: sysex.h,v 1.2 2011/06/27 07:17:44 ratchov Exp $ */
/*
* Copyright (c) 2011 Alexandre Ratchov <alex@caoua.org>
*
@@ -29,6 +29,7 @@
* type/vendor namespace IDs we use
*/
#define SYSEX_TYPE_RT 0x7f /* real-time universal */
+#define SYSEX_TYPE_EDU 0x7d /* non-comercial */
/*
* realtime messages in the "universal real-time" namespace
@@ -43,6 +44,14 @@
#define SYSEX_MMC_LOC_CMD 0x01
/*
+ * aucat-specific messages, in the "edu" namespace
+ */
+#define SYSEX_AUCAT 0x23 /* aucat-specific */
+#define SYSEX_AUCAT_MIXINFO 0x01 /* mixer info */
+#define SYSEX_AUCAT_DUMPREQ 0x02 /* dump request */
+#define SYSEX_AUCAT_DUMPEND 0x03 /* end of dump */
+
+/*
* minimum size of sysex message we accept
*/
#define SYSEX_SIZE(m) (5 + sizeof(struct sysex_ ## m))
@@ -85,6 +94,19 @@ struct sysex {
uint8_t fr;
uint8_t end;
} full;
+ struct sysex_mixinfo {
+ uint8_t chan; /* channel */
+ uint8_t vol; /* current volume */
+#define SYSEX_NAMELEN 10 /* \0 included */
+ uint8_t name[SYSEX_NAMELEN]; /* stream name */
+ uint8_t end;
+ } mixinfo;
+ struct sysex_dumpreq {
+ uint8_t end;
+ } dumpreq;
+ struct sysex_dumpend {
+ uint8_t end;
+ } dumpend;
} u;
};