sndiod: Move MIDI control endpoint to opt structure
authorratchov <ratchov@openbsd.org>
Wed, 3 Mar 2021 10:13:06 +0000 (10:13 +0000)
committerratchov <ratchov@openbsd.org>
Wed, 3 Mar 2021 10:13:06 +0000 (10:13 +0000)
No behavior change.

usr.bin/sndiod/dev.c
usr.bin/sndiod/dev.h
usr.bin/sndiod/opt.c
usr.bin/sndiod/opt.h
usr.bin/sndiod/sock.c

index e47afb3..d725074 100644 (file)
@@ -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 <alex@caoua.org>
  *
@@ -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;
index e1e6680..021902f 100644 (file)
@@ -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 <alex@caoua.org>
  *
@@ -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
index 9e7a221..9b8fb9a 100644 (file)
@@ -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 <alex@caoua.org>
  *
 #include <string.h>
 
 #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);
 }
index b9737f8..593d525 100644 (file)
@@ -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 <alex@caoua.org>
  *
@@ -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];
index 4a425f3..fde276a 100644 (file)
@@ -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 <alex@caoua.org>
  *
@@ -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) {