make midi owner per-output

This commit is contained in:
Alexandre Ratchov 2011-11-15 18:06:47 +01:00
parent 93a88a471d
commit f37ef2f43c
3 changed files with 31 additions and 24 deletions

View File

@ -74,6 +74,9 @@ struct abuf {
unsigned xrun; /* overrun policy, one of XRUN_XXX */
int silence; /* silence to add on next write */
} sub;
struct {
struct abuf *owner; /* current input stream */
} midi;
} w;
};

View File

@ -172,7 +172,6 @@ struct aproc {
int snext; /* to reach the next sample */
} conv;
struct {
struct abuf *owner; /* current input stream */
struct timo timo; /* timout for throtteling */
} thru;
struct {

View File

@ -79,7 +79,7 @@ unsigned common_len[] = { 0, 2, 3, 2, 0, 0, 1, 1 };
* send the message stored in of ibuf->r.midi.msg to obuf
*/
void
thru_flush(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
thru_flush(struct abuf *ibuf, struct abuf *obuf)
{
unsigned ocount, itodo;
unsigned char *odata, *idata;
@ -88,7 +88,7 @@ thru_flush(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
idata = ibuf->r.midi.msg;
#ifdef DEBUG
if (debug_level >= 4) {
aproc_dbg(p);
abuf_dbg(obuf);
dbg_puts(": flushing ");
dbg_putu(itodo);
dbg_puts(" byte message\n");
@ -98,15 +98,15 @@ thru_flush(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
if (!ABUF_WOK(obuf)) {
#ifdef DEBUG
if (debug_level >= 3) {
aproc_dbg(p);
abuf_dbg(obuf);
dbg_puts(": overrun, discarding ");
dbg_putu(obuf->used);
dbg_puts(" bytes\n");
}
#endif
abuf_rdiscard(obuf, obuf->used);
if (p->u.thru.owner == ibuf)
p->u.thru.owner = NULL;
if (obuf->w.midi.owner == ibuf)
obuf->w.midi.owner = NULL;
return;
}
odata = abuf_wgetblk(obuf, &ocount, 0);
@ -118,21 +118,21 @@ thru_flush(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
idata += ocount;
}
ibuf->r.midi.used = 0;
p->u.thru.owner = ibuf;
obuf->w.midi.owner = ibuf;
}
/*
* send the real-time message (one byte) to obuf, similar to thrui_flush()
* send the real-time message (one byte) to obuf, similar to thru_flush()
*/
void
thru_rt(struct aproc *p, struct abuf *ibuf, struct abuf *obuf, unsigned c)
thru_rt(struct abuf *ibuf, struct abuf *obuf, unsigned c)
{
unsigned ocount;
unsigned char *odata;
#ifdef DEBUG
if (debug_level >= 4) {
aproc_dbg(p);
abuf_dbg(obuf);
dbg_puts(": ");
dbg_putx(c);
dbg_puts(": flushing realtime message\n");
@ -143,15 +143,15 @@ thru_rt(struct aproc *p, struct abuf *ibuf, struct abuf *obuf, unsigned c)
if (!ABUF_WOK(obuf)) {
#ifdef DEBUG
if (debug_level >= 3) {
aproc_dbg(p);
abuf_dbg(obuf);
dbg_puts(": overrun, discarding ");
dbg_putu(obuf->used);
dbg_puts(" bytes\n");
}
#endif
abuf_rdiscard(obuf, obuf->used);
if (p->u.thru.owner == ibuf)
p->u.thru.owner = NULL;
if (obuf->w.midi.owner == ibuf)
obuf->w.midi.owner = NULL;
}
odata = abuf_wgetblk(obuf, &ocount, 0);
odata[0] = c;
@ -163,7 +163,7 @@ thru_rt(struct aproc *p, struct abuf *ibuf, struct abuf *obuf, unsigned c)
* use at most ``todo'' bytes (for throttling)
*/
void
thru_bcopy(struct aproc *p, struct abuf *ibuf, struct abuf *obuf, unsigned todo)
thru_bcopy(struct abuf *ibuf, struct abuf *obuf, unsigned todo)
{
unsigned char *idata;
unsigned c, icount, ioffs;
@ -192,22 +192,22 @@ thru_bcopy(struct aproc *p, struct abuf *ibuf, struct abuf *obuf, unsigned todo)
ibuf->r.midi.msg[ibuf->r.midi.used++] = c;
ibuf->r.midi.idx++;
if (ibuf->r.midi.idx == ibuf->r.midi.len) {
thru_flush(p, ibuf, obuf);
thru_flush(ibuf, obuf);
if (ibuf->r.midi.st >= 0xf0)
ibuf->r.midi.st = 0;
ibuf->r.midi.idx = 0;
}
if (ibuf->r.midi.used == MIDI_MSGMAX) {
if (ibuf->r.midi.used == ibuf->r.midi.idx ||
p->u.thru.owner == ibuf)
thru_flush(p, ibuf, obuf);
obuf->w.midi.owner == ibuf)
thru_flush(ibuf, obuf);
else
ibuf->r.midi.used = 0;
}
} else if (c < 0xf8) {
if (ibuf->r.midi.used == ibuf->r.midi.idx ||
p->u.thru.owner == ibuf) {
thru_flush(p, ibuf, obuf);
obuf->w.midi.owner == ibuf) {
thru_flush(ibuf, obuf);
} else
ibuf->r.midi.used = 0;
ibuf->r.midi.msg[0] = c;
@ -216,7 +216,7 @@ thru_bcopy(struct aproc *p, struct abuf *ibuf, struct abuf *obuf, unsigned todo)
common_len[c & 7] :
voice_len[(c >> 4) & 7];
if (ibuf->r.midi.len == 1) {
thru_flush(p, ibuf, obuf);
thru_flush(ibuf, obuf);
ibuf->r.midi.idx = 0;
ibuf->r.midi.st = 0;
ibuf->r.midi.len = 0;
@ -225,7 +225,7 @@ thru_bcopy(struct aproc *p, struct abuf *ibuf, struct abuf *obuf, unsigned todo)
ibuf->r.midi.idx = 1;
}
} else {
thru_rt(p, ibuf, obuf, c);
thru_rt(ibuf, obuf, c);
}
}
}
@ -255,7 +255,7 @@ thru_in(struct aproc *p, struct abuf *ibuf)
inext = LIST_NEXT(i, oent);
if (ibuf->duplex == i)
continue;
thru_bcopy(p, ibuf, i, todo);
thru_bcopy(ibuf, i, todo);
(void)abuf_flush(i);
}
abuf_rdiscard(ibuf, todo);
@ -296,6 +296,12 @@ thru_newin(struct aproc *p, struct abuf *ibuf)
ibuf->tickets = MIDITHRU_XFER;
}
void
thru_newout(struct aproc *p, struct abuf *obuf)
{
obuf->w.midi.owner = NULL;
}
void
thru_done(struct aproc *p)
{
@ -309,7 +315,7 @@ struct aproc_ops thru_ops = {
thru_eof,
thru_hup,
thru_newin,
NULL, /* newout */
thru_newout,
NULL, /* ipos */
NULL, /* opos */
thru_done
@ -344,7 +350,6 @@ thru_new(char *name)
struct aproc *p;
p = aproc_new(&thru_ops, name);
p->u.thru.owner = NULL;
timo_set(&p->u.thru.timo, thru_cb, p);
timo_add(&p->u.thru.timo, MIDITHRU_TIMO);
return p;