From: ratchov Date: Wed, 3 Mar 2021 10:13:06 +0000 (+0000) Subject: sndiod: Move MIDI control endpoint to opt structure X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=5fb8f3c9bc00d61df62d9bc22628ac40e585b306;p=openbsd sndiod: Move MIDI control endpoint to opt structure No behavior change. --- diff --git a/usr.bin/sndiod/dev.c b/usr.bin/sndiod/dev.c index e47afb30314..d725074b77d 100644 --- a/usr.bin/sndiod/dev.c +++ b/usr.bin/sndiod/dev.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dev.c,v 1.92 2021/03/03 10:00:27 ratchov Exp $ */ +/* $OpenBSD: dev.c,v 1.93 2021/03/03 10:13:06 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov * @@ -34,17 +34,12 @@ void zomb_flush(void *); void zomb_eof(void *); void zomb_exit(void *); -void dev_log(struct dev *); void dev_midi_qfr(struct dev *, int); void dev_midi_full(struct dev *); void dev_midi_vol(struct dev *, struct slot *); void dev_midi_master(struct dev *); void dev_midi_slotdesc(struct dev *, struct slot *); void dev_midi_dump(struct dev *); -void dev_midi_imsg(void *, unsigned char *, int); -void dev_midi_omsg(void *, unsigned char *, int); -void dev_midi_fill(void *, int); -void dev_midi_exit(void *); void dev_mix_badd(struct dev *, struct slot *); void dev_mix_adjvol(struct dev *); @@ -71,9 +66,6 @@ void dev_setalt(struct dev *, unsigned int); unsigned int dev_roundof(struct dev *, unsigned int); void dev_wakeup(struct dev *); void dev_sync_attach(struct dev *); -void dev_mmcstart(struct dev *); -void dev_mmcstop(struct dev *); -void dev_mmcloc(struct dev *, unsigned int); void slot_ctlname(struct slot *, char *, size_t); void slot_log(struct slot *); @@ -90,13 +82,6 @@ int slot_skip(struct slot *); void ctl_node_log(struct ctl_node *); void ctl_log(struct ctl *); -struct midiops dev_midiops = { - dev_midi_imsg, - dev_midi_omsg, - dev_midi_fill, - dev_midi_exit -}; - struct slotops zomb_slotops = { zomb_onmove, zomb_onvol, @@ -223,6 +208,21 @@ zomb_exit(void *arg) #endif } +/* + * Broadcast MIDI data to all opts using this device + */ +void +dev_midi_send(struct dev *d, void *msg, int msglen) +{ + struct opt *o; + + for (o = opt_list; o != NULL; o = o->next) { + if (o->dev != d) + continue; + midi_send(o->midi, msg, msglen); + } +} + /* * send a quarter frame MTC message */ @@ -288,7 +288,7 @@ dev_midi_qfr(struct dev *d, int delta) buf[1] = (d->mtc.qfr << 4) | data; d->mtc.qfr++; d->mtc.qfr &= 7; - midi_send(d->midi, buf, 2); + dev_midi_send(d, buf, 2); d->mtc.delta -= qfrlen; } } @@ -340,7 +340,7 @@ dev_midi_full(struct dev *d) x.u.full.fr = d->mtc.fr; x.u.full.end = SYSEX_END; d->mtc.qfr = 0; - midi_send(d->midi, (unsigned char *)&x, SYSEX_SIZE(full)); + dev_midi_send(d, (unsigned char *)&x, SYSEX_SIZE(full)); } /* @@ -354,7 +354,7 @@ dev_midi_vol(struct dev *d, struct slot *s) msg[0] = MIDI_CTL | (s - slot_array); msg[1] = MIDI_CTL_VOL; msg[2] = s->vol; - midi_send(d->midi, msg, 3); + dev_midi_send(d, msg, 3); } /* @@ -394,7 +394,7 @@ dev_midi_master(struct dev *d) x.u.master.fine = 0; x.u.master.coarse = master; x.u.master.end = SYSEX_END; - midi_send(d->midi, (unsigned char *)&x, SYSEX_SIZE(master)); + dev_midi_send(d, (unsigned char *)&x, SYSEX_SIZE(master)); } /* @@ -415,7 +415,7 @@ dev_midi_slotdesc(struct dev *d, struct slot *s) slot_ctlname(s, (char *)x.u.slotdesc.name, SYSEX_NAMELEN); x.u.slotdesc.chan = (s - slot_array); x.u.slotdesc.end = SYSEX_END; - midi_send(d->midi, (unsigned char *)&x, SYSEX_SIZE(slotdesc)); + dev_midi_send(d, (unsigned char *)&x, SYSEX_SIZE(slotdesc)); } void @@ -438,131 +438,7 @@ dev_midi_dump(struct dev *d) x.id0 = SYSEX_AUCAT; x.id1 = SYSEX_AUCAT_DUMPEND; x.u.dumpend.end = SYSEX_END; - midi_send(d->midi, (unsigned char *)&x, SYSEX_SIZE(dumpend)); -} - -void -dev_midi_imsg(void *arg, unsigned char *msg, int len) -{ -#ifdef DEBUG - struct dev *d = arg; - - dev_log(d); - log_puts(": can't receive midi messages\n"); - panic(); -#endif -} - -void -dev_midi_omsg(void *arg, unsigned char *msg, int len) -{ - struct dev *d = arg; - struct sysex *x; - unsigned int fps, chan; - - if ((msg[0] & MIDI_CMDMASK) == MIDI_CTL && msg[1] == MIDI_CTL_VOL) { - chan = msg[0] & MIDI_CHANMASK; - if (chan >= DEV_NSLOT) - return; - if (slot_array[chan].opt == NULL || - slot_array[chan].opt->dev != d) - return; - slot_setvol(slot_array + chan, msg[2]); - ctl_onval(CTL_SLOT_LEVEL, slot_array + chan, NULL, msg[2]); - return; - } - x = (struct sysex *)msg; - if (x->start != SYSEX_START) - return; - if (len < SYSEX_SIZE(empty)) - return; - switch (x->type) { - case SYSEX_TYPE_RT: - if (x->id0 == SYSEX_CONTROL && x->id1 == SYSEX_MASTER) { - if (len == SYSEX_SIZE(master)) { - dev_master(d, x->u.master.coarse); - if (d->master_enabled) { - ctl_onval(CTL_DEV_MASTER, d, NULL, - x->u.master.coarse); - } - } - return; - } - if (x->id0 != SYSEX_MMC) - return; - switch (x->id1) { - case SYSEX_MMC_STOP: - if (len != SYSEX_SIZE(stop)) - return; - if (log_level >= 2) { - dev_log(d); - log_puts(": mmc stop\n"); - } - dev_mmcstop(d); - break; - case SYSEX_MMC_START: - if (len != SYSEX_SIZE(start)) - return; - if (log_level >= 2) { - dev_log(d); - log_puts(": mmc start\n"); - } - dev_mmcstart(d); - break; - case SYSEX_MMC_LOC: - if (len != SYSEX_SIZE(loc) || - x->u.loc.len != SYSEX_MMC_LOC_LEN || - x->u.loc.cmd != SYSEX_MMC_LOC_CMD) - return; - switch (x->u.loc.hr >> 5) { - case MTC_FPS_24: - fps = 24; - break; - case MTC_FPS_25: - fps = 25; - break; - case MTC_FPS_30: - fps = 30; - break; - default: - dev_mmcstop(d); - return; - } - dev_mmcloc(d, - (x->u.loc.hr & 0x1f) * 3600 * MTC_SEC + - x->u.loc.min * 60 * MTC_SEC + - x->u.loc.sec * MTC_SEC + - x->u.loc.fr * (MTC_SEC / fps)); - break; - } - break; - case SYSEX_TYPE_EDU: - if (x->id0 != SYSEX_AUCAT || x->id1 != SYSEX_AUCAT_DUMPREQ) - return; - if (len != SYSEX_SIZE(dumpreq)) - return; - dev_midi_dump(d); - break; - } -} - -void -dev_midi_fill(void *arg, int count) -{ - /* nothing to do */ -} - -void -dev_midi_exit(void *arg) -{ - struct dev *d = arg; - - if (log_level >= 1) { - dev_log(d); - log_puts(": midi end point died\n"); - } - if (d->pstate != DEV_CFG) - dev_close(d); + dev_midi_send(d, (unsigned char *)&x, SYSEX_SIZE(dumpend)); } int @@ -1052,15 +928,6 @@ dev_new(char *path, struct aparams *par, d->num = dev_sndnum++; d->alt_num = -1; - /* - * XXX: below, we allocate a midi input buffer, since we don't - * receive raw midi data, so no need to allocate a input - * ibuf. Possibly set imsg & fill callbacks to NULL and - * use this to in midi_new() to check if buffers need to be - * allocated - */ - d->midi = midi_new(&dev_midiops, d, MODE_MIDIIN | MODE_MIDIOUT); - midi_tag(d->midi, d->num); d->reqpar = *par; d->reqmode = mode; d->reqpchan = d->reqrchan = 0; @@ -1269,6 +1136,7 @@ dev_abort(struct dev *d) int i; struct slot *s; struct ctlslot *c; + struct opt *o; for (i = 0, s = slot_array; i < DEV_NSLOT; i++, s++) { if (s->opt == NULL || s->opt->dev != d) @@ -1289,7 +1157,11 @@ dev_abort(struct dev *d) c->ops = NULL; } - midi_abort(d->midi); + for (o = opt_list; o != NULL; o = o->next) { + if (o->dev != d) + continue; + midi_abort(o->midi); + } if (d->pstate != DEV_CFG) dev_close(d); @@ -1516,7 +1388,6 @@ dev_del(struct dev *d) } #endif } - midi_del(d->midi); *p = d->next; while ((a = d->alt_list) != NULL) { d->alt_list = a->next; diff --git a/usr.bin/sndiod/dev.h b/usr.bin/sndiod/dev.h index e1e6680e162..021902f8071 100644 --- a/usr.bin/sndiod/dev.h +++ b/usr.bin/sndiod/dev.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dev.h,v 1.38 2021/03/03 10:00:27 ratchov Exp $ */ +/* $OpenBSD: dev.h,v 1.39 2021/03/03 10:13:06 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov * @@ -21,6 +21,7 @@ #include "dsp.h" #include "siofile.h" #include "dev_sioctl.h" +#include "opt.h" /* * preallocated audio clients @@ -181,7 +182,6 @@ struct ctlslot { struct dev { struct dev *next; struct slot *slot_list; /* audio streams attached */ - struct midi *midi; /* * name used for various controls @@ -305,11 +305,16 @@ void dev_cycle(struct dev *); /* * midi & midi call-backs */ +void dev_master(struct dev *, unsigned int); +void dev_midi_send(struct dev *, void *, int); +void dev_midi_vol(struct dev *, struct slot *); +void dev_midi_master(struct dev *); +void dev_midi_slotdesc(struct dev *, struct slot *); +void dev_midi_dump(struct dev *); + void dev_mmcstart(struct dev *); void dev_mmcstop(struct dev *); void dev_mmcloc(struct dev *, unsigned int); -void dev_master(struct dev *, unsigned int); -void dev_midi_vol(struct dev *, struct slot *); /* * sio_open(3) like interface for clients diff --git a/usr.bin/sndiod/opt.c b/usr.bin/sndiod/opt.c index 9e7a221f3d5..9b8fb9aca85 100644 --- a/usr.bin/sndiod/opt.c +++ b/usr.bin/sndiod/opt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: opt.c,v 1.6 2021/01/29 11:25:05 ratchov Exp $ */ +/* $OpenBSD: opt.c,v 1.7 2021/03/03 10:13:06 ratchov Exp $ */ /* * Copyright (c) 2008-2011 Alexandre Ratchov * @@ -17,11 +17,154 @@ #include #include "dev.h" +#include "midi.h" #include "opt.h" +#include "sysex.h" #include "utils.h" struct opt *opt_list; +void opt_midi_imsg(void *, unsigned char *, int); +void opt_midi_omsg(void *, unsigned char *, int); +void opt_midi_fill(void *, int); +void opt_midi_exit(void *); + +struct midiops opt_midiops = { + opt_midi_imsg, + opt_midi_omsg, + opt_midi_fill, + opt_midi_exit +}; + +void +opt_midi_imsg(void *arg, unsigned char *msg, int len) +{ +#ifdef DEBUG + struct opt *o = arg; + + log_puts(o->name); + log_puts(": can't receive midi messages\n"); + panic(); +#endif +} + +void +opt_midi_omsg(void *arg, unsigned char *msg, int len) +{ + struct opt *o = arg; + struct sysex *x; + unsigned int fps, chan; + + if ((msg[0] & MIDI_CMDMASK) == MIDI_CTL && msg[1] == MIDI_CTL_VOL) { + chan = msg[0] & MIDI_CHANMASK; + if (chan >= DEV_NSLOT) + return; + if (slot_array[chan].opt == NULL || + slot_array[chan].opt->dev != o->dev) + return; + slot_setvol(slot_array + chan, msg[2]); + ctl_onval(CTL_SLOT_LEVEL, slot_array + chan, NULL, msg[2]); + return; + } + x = (struct sysex *)msg; + if (x->start != SYSEX_START) + return; + if (len < SYSEX_SIZE(empty)) + return; + switch (x->type) { + case SYSEX_TYPE_RT: + if (x->id0 == SYSEX_CONTROL && x->id1 == SYSEX_MASTER) { + if (len == SYSEX_SIZE(master)) { + dev_master(o->dev, x->u.master.coarse); + if (o->dev->master_enabled) { + ctl_onval(CTL_DEV_MASTER, o->dev, NULL, + x->u.master.coarse); + } + } + return; + } + if (x->id0 != SYSEX_MMC) + return; + switch (x->id1) { + case SYSEX_MMC_STOP: + if (len != SYSEX_SIZE(stop)) + return; + if (!o->mmc) + return; + if (log_level >= 2) { + log_puts(o->name); + log_puts(": mmc stop\n"); + } + dev_mmcstop(o->dev); + break; + case SYSEX_MMC_START: + if (len != SYSEX_SIZE(start)) + return; + if (!o->mmc) + return; + if (log_level >= 2) { + log_puts(o->name); + log_puts(": mmc start\n"); + } + dev_mmcstart(o->dev); + break; + case SYSEX_MMC_LOC: + if (len != SYSEX_SIZE(loc) || + x->u.loc.len != SYSEX_MMC_LOC_LEN || + x->u.loc.cmd != SYSEX_MMC_LOC_CMD) + return; + if (!o->mmc) + return; + switch (x->u.loc.hr >> 5) { + case MTC_FPS_24: + fps = 24; + break; + case MTC_FPS_25: + fps = 25; + break; + case MTC_FPS_30: + fps = 30; + break; + default: + dev_mmcstop(o->dev); + return; + } + dev_mmcloc(o->dev, + (x->u.loc.hr & 0x1f) * 3600 * MTC_SEC + + x->u.loc.min * 60 * MTC_SEC + + x->u.loc.sec * MTC_SEC + + x->u.loc.fr * (MTC_SEC / fps)); + break; + } + break; + case SYSEX_TYPE_EDU: + if (x->id0 != SYSEX_AUCAT || x->id1 != SYSEX_AUCAT_DUMPREQ) + return; + if (len != SYSEX_SIZE(dumpreq)) + return; + dev_midi_dump(o->dev); + break; + } +} + +void +opt_midi_fill(void *arg, int count) +{ + /* nothing to do */ +} + +void +opt_midi_exit(void *arg) +{ + struct opt *o = arg; + + if (log_level >= 1) { + log_puts(o->name); + log_puts(": midi end point died\n"); + panic(); + } +} + /* * create a new audio sub-device "configuration" */ @@ -66,6 +209,17 @@ opt_new(struct dev *d, char *name, o = xmalloc(sizeof(struct opt)); o->num = num; o->dev = d; + + /* + * XXX: below, we allocate a midi input buffer, since we don't + * receive raw midi data, so no need to allocate a input + * ibuf. Possibly set imsg & fill callbacks to NULL and + * use this to in midi_new() to check if buffers need to be + * allocated + */ + o->midi = midi_new(&opt_midiops, o, MODE_MIDIIN | MODE_MIDIOUT); + midi_tag(o->midi, o->num); + if (mode & MODE_PLAY) { o->pmin = pmin; o->pmax = pmax; @@ -144,6 +298,7 @@ opt_del(struct opt *o) } #endif } + midi_del(o->midi); *po = o->next; xfree(o); } diff --git a/usr.bin/sndiod/opt.h b/usr.bin/sndiod/opt.h index b9737f8ea34..593d5250f54 100644 --- a/usr.bin/sndiod/opt.h +++ b/usr.bin/sndiod/opt.h @@ -1,4 +1,4 @@ -/* $OpenBSD: opt.h,v 1.4 2021/01/29 11:25:05 ratchov Exp $ */ +/* $OpenBSD: opt.h,v 1.5 2021/03/03 10:13:06 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov * @@ -24,6 +24,7 @@ struct dev; struct opt { struct opt *next; struct dev *dev; + struct midi *midi; int num; #define OPT_NAMEMAX 11 char name[OPT_NAMEMAX + 1]; diff --git a/usr.bin/sndiod/sock.c b/usr.bin/sndiod/sock.c index 4a425f32328..fde276ac40a 100644 --- a/usr.bin/sndiod/sock.c +++ b/usr.bin/sndiod/sock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sock.c,v 1.42 2021/03/03 10:00:27 ratchov Exp $ */ +/* $OpenBSD: sock.c,v 1.43 2021/03/03 10:13:06 ratchov Exp $ */ /* * Copyright (c) 2008-2012 Alexandre Ratchov * @@ -880,9 +880,12 @@ sock_hello(struct sock *f) d = dev_bynum(p->devnum); if (d == NULL) return 0; + opt = opt_byname(d, p->opt); + if (opt == NULL) + return 0; if (!dev_ref(d)) return 0; - midi_tag(f->midi, p->devnum); + midi_tag(f->midi, opt->num); } else if (p->devnum < 32) { midi_tag(f->midi, p->devnum); } else if (p->devnum < 48) {