version 1.9, 2009/09/27 11:51:20 |
version 1.10, 2009/10/09 16:49:48 |
|
|
unsigned common_len[] = { 0, 2, 3, 2, 0, 0, 1, 1 }; |
unsigned common_len[] = { 0, 2, 3, 2, 0, 0, 1, 1 }; |
|
|
/* |
/* |
* send the message stored in of ibuf->mdata to obuf |
* send the message stored in of ibuf->r.midi.msg to obuf |
*/ |
*/ |
void |
void |
thru_flush(struct aproc *p, struct abuf *ibuf, struct abuf *obuf) |
thru_flush(struct aproc *p, struct abuf *ibuf, struct abuf *obuf) |
|
|
unsigned ocount, itodo; |
unsigned ocount, itodo; |
unsigned char *odata, *idata; |
unsigned char *odata, *idata; |
|
|
itodo = ibuf->mused; |
itodo = ibuf->r.midi.used; |
idata = ibuf->mdata; |
idata = ibuf->r.midi.msg; |
while (itodo > 0) { |
while (itodo > 0) { |
if (!ABUF_WOK(obuf)) { |
if (!ABUF_WOK(obuf)) { |
abuf_rdiscard(obuf, obuf->used); |
abuf_rdiscard(obuf, obuf->used); |
|
|
itodo -= ocount; |
itodo -= ocount; |
idata += ocount; |
idata += ocount; |
} |
} |
ibuf->mused = 0; |
ibuf->r.midi.used = 0; |
p->u.thru.owner = ibuf; |
p->u.thru.owner = ibuf; |
} |
} |
|
|
|
|
c = *idata++; |
c = *idata++; |
icount--; |
icount--; |
if (c < 0x80) { |
if (c < 0x80) { |
if (ibuf->mindex == 0 && ibuf->mstatus) { |
if (ibuf->r.midi.idx == 0 && ibuf->r.midi.st) { |
ibuf->mdata[ibuf->mused++] = ibuf->mstatus; |
ibuf->r.midi.msg[ibuf->r.midi.used++] = ibuf->r.midi.st; |
ibuf->mindex++; |
ibuf->r.midi.idx++; |
} |
} |
ibuf->mdata[ibuf->mused++] = c; |
ibuf->r.midi.msg[ibuf->r.midi.used++] = c; |
ibuf->mindex++; |
ibuf->r.midi.idx++; |
if (ibuf->mindex == ibuf->mlen) { |
if (ibuf->r.midi.idx == ibuf->r.midi.len) { |
thru_flush(p, ibuf, obuf); |
thru_flush(p, ibuf, obuf); |
if (ibuf->mstatus >= 0xf0) |
if (ibuf->r.midi.st >= 0xf0) |
ibuf->mstatus = 0; |
ibuf->r.midi.st = 0; |
ibuf->mindex = 0; |
ibuf->r.midi.idx = 0; |
} |
} |
if (ibuf->mused == MDATA_NMAX) { |
if (ibuf->r.midi.used == MIDI_MSGMAX) { |
if (ibuf->mused == ibuf->mindex || |
if (ibuf->r.midi.used == ibuf->r.midi.idx || |
p->u.thru.owner == ibuf) |
p->u.thru.owner == ibuf) |
thru_flush(p, ibuf, obuf); |
thru_flush(p, ibuf, obuf); |
else |
else |
ibuf->mused = 0; |
ibuf->r.midi.used = 0; |
} |
} |
} else if (c < 0xf8) { |
} else if (c < 0xf8) { |
if (ibuf->mused == ibuf->mindex || |
if (ibuf->r.midi.used == ibuf->r.midi.idx || |
p->u.thru.owner == ibuf) { |
p->u.thru.owner == ibuf) { |
thru_flush(p, ibuf, obuf); |
thru_flush(p, ibuf, obuf); |
} else |
} else |
ibuf->mused = 0; |
ibuf->r.midi.used = 0; |
ibuf->mdata[0] = c; |
ibuf->r.midi.msg[0] = c; |
ibuf->mused = 1; |
ibuf->r.midi.used = 1; |
ibuf->mlen = (c >= 0xf0) ? |
ibuf->r.midi.len = (c >= 0xf0) ? |
common_len[c & 7] : |
common_len[c & 7] : |
voice_len[(c >> 4) & 7]; |
voice_len[(c >> 4) & 7]; |
if (ibuf->mlen == 1) { |
if (ibuf->r.midi.len == 1) { |
thru_flush(p, ibuf, obuf); |
thru_flush(p, ibuf, obuf); |
ibuf->mindex = 0; |
ibuf->r.midi.idx = 0; |
ibuf->mstatus = 0; |
ibuf->r.midi.st = 0; |
ibuf->mlen = 0; |
ibuf->r.midi.len = 0; |
} else { |
} else { |
ibuf->mstatus = c; |
ibuf->r.midi.st = c; |
ibuf->mindex = 1; |
ibuf->r.midi.idx = 1; |
} |
} |
} else { |
} else { |
thru_rt(p, ibuf, obuf, c); |
thru_rt(p, ibuf, obuf, c); |
|
|
|
|
if (!ABUF_ROK(ibuf)) |
if (!ABUF_ROK(ibuf)) |
return 0; |
return 0; |
if (ibuf->mtickets == 0) { |
if (ibuf->tickets == 0) { |
return 0; |
return 0; |
} |
} |
todo = ibuf->used; |
todo = ibuf->used; |
if (todo > ibuf->mtickets) |
if (todo > ibuf->tickets) |
todo = ibuf->mtickets; |
todo = ibuf->tickets; |
ibuf->mtickets -= todo; |
ibuf->tickets -= todo; |
for (i = LIST_FIRST(&p->obuflist); i != NULL; i = inext) { |
for (i = LIST_FIRST(&p->obuflist); i != NULL; i = inext) { |
inext = LIST_NEXT(i, oent); |
inext = LIST_NEXT(i, oent); |
if (ibuf->duplex == i) |
if (ibuf->duplex == i) |
|
|
void |
void |
thru_newin(struct aproc *p, struct abuf *ibuf) |
thru_newin(struct aproc *p, struct abuf *ibuf) |
{ |
{ |
ibuf->mused = 0; |
ibuf->r.midi.used = 0; |
ibuf->mlen = 0; |
ibuf->r.midi.len = 0; |
ibuf->mindex = 0; |
ibuf->r.midi.idx = 0; |
ibuf->mstatus = 0; |
ibuf->r.midi.st = 0; |
ibuf->mtickets = MIDITHRU_XFER; |
ibuf->tickets = MIDITHRU_XFER; |
} |
} |
|
|
void |
void |
|
|
|
|
for (i = LIST_FIRST(&p->ibuflist); i != NULL; i = inext) { |
for (i = LIST_FIRST(&p->ibuflist); i != NULL; i = inext) { |
inext = LIST_NEXT(i, ient); |
inext = LIST_NEXT(i, ient); |
tickets = i->mtickets; |
tickets = i->tickets; |
i->mtickets = MIDITHRU_XFER; |
i->tickets = MIDITHRU_XFER; |
if (tickets == 0) |
if (tickets == 0) |
abuf_run(i); |
abuf_run(i); |
} |
} |
|
|
{ |
{ |
unsigned chan; |
unsigned chan; |
struct ctl_slot *slot; |
struct ctl_slot *slot; |
if ((ibuf->mdata[0] & MIDI_CMDMASK) == MIDI_CTL && |
if ((ibuf->r.midi.msg[0] & MIDI_CMDMASK) == MIDI_CTL && |
ibuf->mdata[1] == MIDI_CTLVOL) { |
ibuf->r.midi.msg[1] == MIDI_CTLVOL) { |
chan = ibuf->mdata[0] & MIDI_CHANMASK; |
chan = ibuf->r.midi.msg[0] & MIDI_CHANMASK; |
if (chan >= CTL_NSLOT) |
if (chan >= CTL_NSLOT) |
return; |
return; |
slot = p->u.ctl.slot + chan; |
slot = p->u.ctl.slot + chan; |
if (slot->cb == NULL) |
if (slot->cb == NULL) |
return; |
return; |
slot->vol = ibuf->mdata[2]; |
slot->vol = ibuf->r.midi.msg[2]; |
slot->cb(slot->arg, slot->vol); |
slot->cb(slot->arg, slot->vol); |
ctl_sendmsg(p, ibuf, ibuf->mdata, ibuf->mlen); |
ctl_sendmsg(p, ibuf, ibuf->r.midi.msg, ibuf->r.midi.len); |
} |
} |
} |
} |
|
|
|
|
if (c >= 0xf8) { |
if (c >= 0xf8) { |
/* clock events not used yet */ |
/* clock events not used yet */ |
} else if (c >= 0xf0) { |
} else if (c >= 0xf0) { |
if (ibuf->mstatus == 0xf0 && c == 0xf7 && |
if (ibuf->r.midi.st == 0xf0 && c == 0xf7 && |
ibuf->mindex < MDATA_NMAX) { |
ibuf->r.midi.idx < MIDI_MSGMAX) { |
ibuf->mdata[ibuf->mindex++] = c; |
ibuf->r.midi.msg[ibuf->r.midi.idx++] = c; |
ctl_ev(p, ibuf); |
ctl_ev(p, ibuf); |
continue; |
continue; |
} |
} |
ibuf->mdata[0] = c; |
ibuf->r.midi.msg[0] = c; |
ibuf->mlen = common_len[c & 7]; |
ibuf->r.midi.len = common_len[c & 7]; |
ibuf->mstatus = c; |
ibuf->r.midi.st = c; |
ibuf->mindex = 1; |
ibuf->r.midi.idx = 1; |
} else if (c >= 0x80) { |
} else if (c >= 0x80) { |
ibuf->mdata[0] = c; |
ibuf->r.midi.msg[0] = c; |
ibuf->mlen = voice_len[(c >> 4) & 7]; |
ibuf->r.midi.len = voice_len[(c >> 4) & 7]; |
ibuf->mstatus = c; |
ibuf->r.midi.st = c; |
ibuf->mindex = 1; |
ibuf->r.midi.idx = 1; |
} else if (ibuf->mstatus) { |
} else if (ibuf->r.midi.st) { |
if (ibuf->mindex == MDATA_NMAX) |
if (ibuf->r.midi.idx == MIDI_MSGMAX) |
continue; |
continue; |
if (ibuf->mindex == 0) |
if (ibuf->r.midi.idx == 0) |
ibuf->mdata[ibuf->mindex++] = ibuf->mstatus; |
ibuf->r.midi.msg[ibuf->r.midi.idx++] = ibuf->r.midi.st; |
ibuf->mdata[ibuf->mindex++] = c; |
ibuf->r.midi.msg[ibuf->r.midi.idx++] = c; |
if (ibuf->mindex == ibuf->mlen) { |
if (ibuf->r.midi.idx == ibuf->r.midi.len) { |
ctl_ev(p, ibuf); |
ctl_ev(p, ibuf); |
ibuf->mindex = 0; |
ibuf->r.midi.idx = 0; |
} |
} |
} |
} |
} |
} |
|
|
void |
void |
ctl_newin(struct aproc *p, struct abuf *ibuf) |
ctl_newin(struct aproc *p, struct abuf *ibuf) |
{ |
{ |
ibuf->mused = 0; |
ibuf->r.midi.used = 0; |
ibuf->mlen = 0; |
ibuf->r.midi.len = 0; |
ibuf->mindex = 0; |
ibuf->r.midi.idx = 0; |
ibuf->mstatus = 0; |
ibuf->r.midi.st = 0; |
} |
} |
|
|
void |
void |