diff options
author | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2011-06-27 07:17:45 +0000 |
---|---|---|
committer | Alexandre Ratchov <ratchov@cvs.openbsd.org> | 2011-06-27 07:17:45 +0000 |
commit | 1f581fa2caf2cd2dabe56f18b2c4349672e8dc90 (patch) | |
tree | 9f60e09976771a0a2386cad2e38c4ac8eda6c42a | |
parent | 685f9a3c03f78a2aa869a5b1b1be78f891d74917 (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.c | 57 | ||||
-rw-r--r-- | usr.bin/aucat/sysex.h | 24 |
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; }; |