summaryrefslogtreecommitdiff
path: root/usr.bin/aucat
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/aucat')
-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;
};