version 1.92, 2021/03/03 10:00:27 |
version 1.93, 2021/03/03 10:13:06 |
|
|
void zomb_eof(void *); |
void zomb_eof(void *); |
void zomb_exit(void *); |
void zomb_exit(void *); |
|
|
void dev_log(struct dev *); |
|
void dev_midi_qfr(struct dev *, int); |
void dev_midi_qfr(struct dev *, int); |
void dev_midi_full(struct dev *); |
void dev_midi_full(struct dev *); |
void dev_midi_vol(struct dev *, struct slot *); |
void dev_midi_vol(struct dev *, struct slot *); |
void dev_midi_master(struct dev *); |
void dev_midi_master(struct dev *); |
void dev_midi_slotdesc(struct dev *, struct slot *); |
void dev_midi_slotdesc(struct dev *, struct slot *); |
void dev_midi_dump(struct dev *); |
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_badd(struct dev *, struct slot *); |
void dev_mix_adjvol(struct dev *); |
void dev_mix_adjvol(struct dev *); |
|
|
unsigned int dev_roundof(struct dev *, unsigned int); |
unsigned int dev_roundof(struct dev *, unsigned int); |
void dev_wakeup(struct dev *); |
void dev_wakeup(struct dev *); |
void dev_sync_attach(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_ctlname(struct slot *, char *, size_t); |
void slot_log(struct slot *); |
void slot_log(struct slot *); |
|
|
void ctl_node_log(struct ctl_node *); |
void ctl_node_log(struct ctl_node *); |
void ctl_log(struct ctl *); |
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 = { |
struct slotops zomb_slotops = { |
zomb_onmove, |
zomb_onmove, |
zomb_onvol, |
zomb_onvol, |
|
|
} |
} |
|
|
/* |
/* |
|
* 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 |
* send a quarter frame MTC message |
*/ |
*/ |
void |
void |
|
|
buf[1] = (d->mtc.qfr << 4) | data; |
buf[1] = (d->mtc.qfr << 4) | data; |
d->mtc.qfr++; |
d->mtc.qfr++; |
d->mtc.qfr &= 7; |
d->mtc.qfr &= 7; |
midi_send(d->midi, buf, 2); |
dev_midi_send(d, buf, 2); |
d->mtc.delta -= qfrlen; |
d->mtc.delta -= qfrlen; |
} |
} |
} |
} |
|
|
x.u.full.fr = d->mtc.fr; |
x.u.full.fr = d->mtc.fr; |
x.u.full.end = SYSEX_END; |
x.u.full.end = SYSEX_END; |
d->mtc.qfr = 0; |
d->mtc.qfr = 0; |
midi_send(d->midi, (unsigned char *)&x, SYSEX_SIZE(full)); |
dev_midi_send(d, (unsigned char *)&x, SYSEX_SIZE(full)); |
} |
} |
|
|
/* |
/* |
|
|
msg[0] = MIDI_CTL | (s - slot_array); |
msg[0] = MIDI_CTL | (s - slot_array); |
msg[1] = MIDI_CTL_VOL; |
msg[1] = MIDI_CTL_VOL; |
msg[2] = s->vol; |
msg[2] = s->vol; |
midi_send(d->midi, msg, 3); |
dev_midi_send(d, msg, 3); |
} |
} |
|
|
/* |
/* |
|
|
x.u.master.fine = 0; |
x.u.master.fine = 0; |
x.u.master.coarse = master; |
x.u.master.coarse = master; |
x.u.master.end = SYSEX_END; |
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)); |
} |
} |
|
|
/* |
/* |
|
|
slot_ctlname(s, (char *)x.u.slotdesc.name, SYSEX_NAMELEN); |
slot_ctlname(s, (char *)x.u.slotdesc.name, SYSEX_NAMELEN); |
x.u.slotdesc.chan = (s - slot_array); |
x.u.slotdesc.chan = (s - slot_array); |
x.u.slotdesc.end = SYSEX_END; |
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 |
void |
|
|
x.id0 = SYSEX_AUCAT; |
x.id0 = SYSEX_AUCAT; |
x.id1 = SYSEX_AUCAT_DUMPEND; |
x.id1 = SYSEX_AUCAT_DUMPEND; |
x.u.dumpend.end = SYSEX_END; |
x.u.dumpend.end = SYSEX_END; |
midi_send(d->midi, (unsigned char *)&x, SYSEX_SIZE(dumpend)); |
dev_midi_send(d, (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); |
|
} |
|
|
|
int |
int |
slot_skip(struct slot *s) |
slot_skip(struct slot *s) |
{ |
{ |
|
|
d->num = dev_sndnum++; |
d->num = dev_sndnum++; |
d->alt_num = -1; |
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->reqpar = *par; |
d->reqmode = mode; |
d->reqmode = mode; |
d->reqpchan = d->reqrchan = 0; |
d->reqpchan = d->reqrchan = 0; |
|
|
int i; |
int i; |
struct slot *s; |
struct slot *s; |
struct ctlslot *c; |
struct ctlslot *c; |
|
struct opt *o; |
|
|
for (i = 0, s = slot_array; i < DEV_NSLOT; i++, s++) { |
for (i = 0, s = slot_array; i < DEV_NSLOT; i++, s++) { |
if (s->opt == NULL || s->opt->dev != d) |
if (s->opt == NULL || s->opt->dev != d) |
|
|
c->ops = NULL; |
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) |
if (d->pstate != DEV_CFG) |
dev_close(d); |
dev_close(d); |
|
|
} |
} |
#endif |
#endif |
} |
} |
midi_del(d->midi); |
|
*p = d->next; |
*p = d->next; |
while ((a = d->alt_list) != NULL) { |
while ((a = d->alt_list) != NULL) { |
d->alt_list = a->next; |
d->alt_list = a->next; |