mirror of https://github.com/ericonr/sndio.git
Move MIDI control endpoint to opt structure
This commit is contained in:
parent
bb27629080
commit
ada702087d
|
@ -55,23 +55,26 @@ sndiod: ${OBJS}
|
|||
|
||||
abuf.o: abuf.c abuf.h utils.h
|
||||
dev.o: dev.c ../bsd-compat/bsd-compat.h abuf.h defs.h dev.h \
|
||||
dsp.h siofile.h file.h midi.h miofile.h sysex.h utils.h
|
||||
dsp.h siofile.h file.h dev_sioctl.h opt.h midi.h \
|
||||
miofile.h sysex.h utils.h
|
||||
dev_sioctl.o: dev_sioctl.c abuf.h defs.h dev.h dsp.h siofile.h file.h \
|
||||
utils.h
|
||||
dev_sioctl.h opt.h utils.h ../bsd-compat/bsd-compat.h
|
||||
dsp.o: dsp.c dsp.h defs.h utils.h
|
||||
file.o: file.c file.h utils.h
|
||||
file.o: file.c ../bsd-compat/bsd-compat.h file.h utils.h
|
||||
listen.o: listen.c listen.h file.h sock.h ../libsndio/amsg.h \
|
||||
utils.h ../bsd-compat/bsd-compat.h
|
||||
midi.o: midi.c abuf.h defs.h dev.h dsp.h siofile.h file.h midi.h \
|
||||
miofile.h sysex.h utils.h ../bsd-compat/bsd-compat.h
|
||||
midi.o: midi.c abuf.h defs.h dev.h dsp.h siofile.h file.h \
|
||||
dev_sioctl.h opt.h midi.h miofile.h sysex.h utils.h \
|
||||
../bsd-compat/bsd-compat.h
|
||||
miofile.o: miofile.c defs.h file.h midi.h abuf.h miofile.h utils.h
|
||||
opt.o: opt.c dev.h abuf.h dsp.h defs.h siofile.h file.h opt.h \
|
||||
utils.h
|
||||
opt.o: opt.c dev.h abuf.h dsp.h defs.h siofile.h file.h \
|
||||
dev_sioctl.h opt.h midi.h miofile.h sysex.h utils.h
|
||||
siofile.o: siofile.c abuf.h defs.h dev.h dsp.h siofile.h file.h \
|
||||
utils.h
|
||||
dev_sioctl.h opt.h utils.h
|
||||
sndiod.o: sndiod.c ../libsndio/amsg.h defs.h dev.h abuf.h dsp.h \
|
||||
siofile.h file.h listen.h midi.h miofile.h opt.h sock.h \
|
||||
utils.h ../bsd-compat/bsd-compat.h
|
||||
sock.o: sock.c abuf.h defs.h dev.h dsp.h siofile.h file.h midi.h \
|
||||
miofile.h opt.h sock.h ../libsndio/amsg.h utils.h
|
||||
siofile.h file.h dev_sioctl.h opt.h listen.h midi.h \
|
||||
miofile.h sock.h utils.h ../bsd-compat/bsd-compat.h
|
||||
sock.o: sock.c abuf.h defs.h dev.h dsp.h siofile.h file.h \
|
||||
dev_sioctl.h opt.h midi.h miofile.h sock.h \
|
||||
../libsndio/amsg.h utils.h ../bsd-compat/bsd-compat.h
|
||||
utils.o: utils.c utils.h
|
||||
|
|
183
sndiod/dev.c
183
sndiod/dev.c
|
@ -35,17 +35,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 *);
|
||||
|
@ -72,9 +67,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 *);
|
||||
|
@ -91,13 +83,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,
|
||||
|
@ -224,6 +209,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
|
||||
*/
|
||||
|
@ -289,7 +289,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;
|
||||
}
|
||||
}
|
||||
|
@ -341,7 +341,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));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -355,7 +355,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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -395,7 +395,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));
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -416,7 +416,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
|
||||
|
@ -439,131 +439,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
|
||||
|
@ -1053,15 +929,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;
|
||||
|
@ -1270,6 +1137,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)
|
||||
|
@ -1290,7 +1158,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);
|
||||
|
@ -1517,7 +1389,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;
|
||||
|
|
11
sndiod/dev.h
11
sndiod/dev.h
|
@ -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
|
||||
|
|
155
sndiod/opt.c
155
sndiod/opt.c
|
@ -17,11 +17,154 @@
|
|||
#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);
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -869,9 +869,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) {
|
||||
|
|
Loading…
Reference in New Issue