mirror of https://github.com/ericonr/sndio.git
make midi owner per-output
This commit is contained in:
parent
93a88a471d
commit
f37ef2f43c
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
51
aucat/midi.c
51
aucat/midi.c
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue