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 */ unsigned xrun; /* overrun policy, one of XRUN_XXX */
int silence; /* silence to add on next write */ int silence; /* silence to add on next write */
} sub; } sub;
struct {
struct abuf *owner; /* current input stream */
} midi;
} w; } w;
}; };

View File

@ -172,7 +172,6 @@ struct aproc {
int snext; /* to reach the next sample */ int snext; /* to reach the next sample */
} conv; } conv;
struct { struct {
struct abuf *owner; /* current input stream */
struct timo timo; /* timout for throtteling */ struct timo timo; /* timout for throtteling */
} thru; } thru;
struct { 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 * 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 abuf *ibuf, struct abuf *obuf)
{ {
unsigned ocount, itodo; unsigned ocount, itodo;
unsigned char *odata, *idata; unsigned char *odata, *idata;
@ -88,7 +88,7 @@ thru_flush(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
idata = ibuf->r.midi.msg; idata = ibuf->r.midi.msg;
#ifdef DEBUG #ifdef DEBUG
if (debug_level >= 4) { if (debug_level >= 4) {
aproc_dbg(p); abuf_dbg(obuf);
dbg_puts(": flushing "); dbg_puts(": flushing ");
dbg_putu(itodo); dbg_putu(itodo);
dbg_puts(" byte message\n"); dbg_puts(" byte message\n");
@ -98,15 +98,15 @@ thru_flush(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
if (!ABUF_WOK(obuf)) { if (!ABUF_WOK(obuf)) {
#ifdef DEBUG #ifdef DEBUG
if (debug_level >= 3) { if (debug_level >= 3) {
aproc_dbg(p); abuf_dbg(obuf);
dbg_puts(": overrun, discarding "); dbg_puts(": overrun, discarding ");
dbg_putu(obuf->used); dbg_putu(obuf->used);
dbg_puts(" bytes\n"); dbg_puts(" bytes\n");
} }
#endif #endif
abuf_rdiscard(obuf, obuf->used); abuf_rdiscard(obuf, obuf->used);
if (p->u.thru.owner == ibuf) if (obuf->w.midi.owner == ibuf)
p->u.thru.owner = NULL; obuf->w.midi.owner = NULL;
return; return;
} }
odata = abuf_wgetblk(obuf, &ocount, 0); odata = abuf_wgetblk(obuf, &ocount, 0);
@ -118,21 +118,21 @@ thru_flush(struct aproc *p, struct abuf *ibuf, struct abuf *obuf)
idata += ocount; idata += ocount;
} }
ibuf->r.midi.used = 0; 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 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 ocount;
unsigned char *odata; unsigned char *odata;
#ifdef DEBUG #ifdef DEBUG
if (debug_level >= 4) { if (debug_level >= 4) {
aproc_dbg(p); abuf_dbg(obuf);
dbg_puts(": "); dbg_puts(": ");
dbg_putx(c); dbg_putx(c);
dbg_puts(": flushing realtime message\n"); 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)) { if (!ABUF_WOK(obuf)) {
#ifdef DEBUG #ifdef DEBUG
if (debug_level >= 3) { if (debug_level >= 3) {
aproc_dbg(p); abuf_dbg(obuf);
dbg_puts(": overrun, discarding "); dbg_puts(": overrun, discarding ");
dbg_putu(obuf->used); dbg_putu(obuf->used);
dbg_puts(" bytes\n"); dbg_puts(" bytes\n");
} }
#endif #endif
abuf_rdiscard(obuf, obuf->used); abuf_rdiscard(obuf, obuf->used);
if (p->u.thru.owner == ibuf) if (obuf->w.midi.owner == ibuf)
p->u.thru.owner = NULL; obuf->w.midi.owner = NULL;
} }
odata = abuf_wgetblk(obuf, &ocount, 0); odata = abuf_wgetblk(obuf, &ocount, 0);
odata[0] = c; 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) * use at most ``todo'' bytes (for throttling)
*/ */
void 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 char *idata;
unsigned c, icount, ioffs; 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.msg[ibuf->r.midi.used++] = c;
ibuf->r.midi.idx++; ibuf->r.midi.idx++;
if (ibuf->r.midi.idx == ibuf->r.midi.len) { if (ibuf->r.midi.idx == ibuf->r.midi.len) {
thru_flush(p, ibuf, obuf); thru_flush(ibuf, obuf);
if (ibuf->r.midi.st >= 0xf0) if (ibuf->r.midi.st >= 0xf0)
ibuf->r.midi.st = 0; ibuf->r.midi.st = 0;
ibuf->r.midi.idx = 0; ibuf->r.midi.idx = 0;
} }
if (ibuf->r.midi.used == MIDI_MSGMAX) { if (ibuf->r.midi.used == MIDI_MSGMAX) {
if (ibuf->r.midi.used == ibuf->r.midi.idx || if (ibuf->r.midi.used == ibuf->r.midi.idx ||
p->u.thru.owner == ibuf) obuf->w.midi.owner == ibuf)
thru_flush(p, ibuf, obuf); thru_flush(ibuf, obuf);
else else
ibuf->r.midi.used = 0; ibuf->r.midi.used = 0;
} }
} else if (c < 0xf8) { } else if (c < 0xf8) {
if (ibuf->r.midi.used == ibuf->r.midi.idx || if (ibuf->r.midi.used == ibuf->r.midi.idx ||
p->u.thru.owner == ibuf) { obuf->w.midi.owner == ibuf) {
thru_flush(p, ibuf, obuf); thru_flush(ibuf, obuf);
} else } else
ibuf->r.midi.used = 0; ibuf->r.midi.used = 0;
ibuf->r.midi.msg[0] = c; 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] : common_len[c & 7] :
voice_len[(c >> 4) & 7]; voice_len[(c >> 4) & 7];
if (ibuf->r.midi.len == 1) { if (ibuf->r.midi.len == 1) {
thru_flush(p, ibuf, obuf); thru_flush(ibuf, obuf);
ibuf->r.midi.idx = 0; ibuf->r.midi.idx = 0;
ibuf->r.midi.st = 0; ibuf->r.midi.st = 0;
ibuf->r.midi.len = 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; ibuf->r.midi.idx = 1;
} }
} else { } 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); inext = LIST_NEXT(i, oent);
if (ibuf->duplex == i) if (ibuf->duplex == i)
continue; continue;
thru_bcopy(p, ibuf, i, todo); thru_bcopy(ibuf, i, todo);
(void)abuf_flush(i); (void)abuf_flush(i);
} }
abuf_rdiscard(ibuf, todo); abuf_rdiscard(ibuf, todo);
@ -296,6 +296,12 @@ thru_newin(struct aproc *p, struct abuf *ibuf)
ibuf->tickets = MIDITHRU_XFER; ibuf->tickets = MIDITHRU_XFER;
} }
void
thru_newout(struct aproc *p, struct abuf *obuf)
{
obuf->w.midi.owner = NULL;
}
void void
thru_done(struct aproc *p) thru_done(struct aproc *p)
{ {
@ -309,7 +315,7 @@ struct aproc_ops thru_ops = {
thru_eof, thru_eof,
thru_hup, thru_hup,
thru_newin, thru_newin,
NULL, /* newout */ thru_newout,
NULL, /* ipos */ NULL, /* ipos */
NULL, /* opos */ NULL, /* opos */
thru_done thru_done
@ -344,7 +350,6 @@ thru_new(char *name)
struct aproc *p; struct aproc *p;
p = aproc_new(&thru_ops, name); p = aproc_new(&thru_ops, name);
p->u.thru.owner = NULL;
timo_set(&p->u.thru.timo, thru_cb, p); timo_set(&p->u.thru.timo, thru_cb, p);
timo_add(&p->u.thru.timo, MIDITHRU_TIMO); timo_add(&p->u.thru.timo, MIDITHRU_TIMO);
return p; return p;