Fix midi output "ownership". Check if clockticks are out of bounds to

detect bogus libsndio backends. Use a midithru for device control.
This commit is contained in:
Alexandre Ratchov 2012-09-26 00:07:28 +02:00
parent 0127efd381
commit 832cb8bbe7
6 changed files with 37 additions and 12 deletions

View File

@ -634,13 +634,14 @@ dev_mix_cycle(struct dev *d)
continue;
}
#ifdef DEBUG
s->delay -= s->round;
if (log_level >= 4) {
slot_log(s);
log_puts(": mixing, drop = ");
log_puti(s->mix.drop);
log_puts(" cycles\n");
}
#endif
#endif
slot_mix_drop(s);
if (s->mix.drop < 0) {
s->mix.drop++;
@ -875,6 +876,9 @@ dev_onmove(struct dev *d, int delta)
pos = (long long)delta * s->round + s->delta_rem;
s->delta_rem = pos % d->round;
s->delta += pos / (int)d->round;
#ifdef DEBUG
s->delay += pos / (int)d->round;
#endif
if (s->delta >= 0)
s->ops->onmove(s->arg, delta);
}
@ -960,6 +964,7 @@ dev_new(char *path, struct aparams *par,
d = xmalloc(sizeof(struct dev));
d->num = dev_sndnum++;
d->midi = midi_new(&dev_midiops, d, MODE_MIDIIN | MODE_MIDIOUT);
midi_tag(d->midi, d->num);
d->path = path;
d->reqpar = *par;
d->reqmode = mode;
@ -1613,6 +1618,7 @@ slot_attach(struct slot *s)
s->delta_rem = 0;
s->pstate = SLOT_RUN;
#ifdef DEBUG
s->delay = 0;
if (log_level >= 3) {
slot_log(s);
log_puts(": attached at ");

View File

@ -45,6 +45,9 @@ struct slot {
struct dev *dev; /* device this belongs to */
void *arg; /* user data for callbacks */
struct aparams par; /* socket side params */
#ifdef DEBUG
int delay;
#endif
struct {
int weight; /* dynamic range */
int maxweight; /* max dynamic range allowed */

View File

@ -60,7 +60,7 @@ unsigned int midi_portnum = 0;
struct midithru {
unsigned txmask;
#define MIDITHRU_NMAX 16
#define MIDITHRU_NMAX 32
} midithru[MIDITHRU_NMAX];
/*
@ -214,10 +214,14 @@ midi_send(struct midi *iep, unsigned char *msg, int size)
if ((iep->txmask & (1 << i)) == 0)
continue;
oep = midi_ep + i;
if (msg[0] == SYSEX_START)
if (msg[0] <= 0x7f) {
/* data (sysex continuation) */
if (oep->owner != iep)
continue;
} else if (msg[0] <= 0xf7) {
/* new running status */
oep->owner = iep;
else if (oep->owner != iep)
continue;
}
#ifdef DEBUG
if (log_level >= 4) {
midi_log(iep);

View File

@ -38,6 +38,7 @@ struct siofile {
#ifdef DEBUG
long long wtime, utime;
long long sum_wtime, sum_utime;
int delay;
#endif
struct dev *dev;
struct file *file;
@ -97,6 +98,16 @@ siofile_onmove(void *arg, int delta)
f->sum_wtime += file_wtime - f->wtime;
f->wtime = file_wtime;
f->utime = file_utime;
f->delay += delta;
if (f->delay > 0) {
siofile_log(f);
log_puts(": clock ahead of buffer: delay = ");
log_puti(f->delay);
log_puts(", bufsz = \n");
log_puti(f->dev->bufsz);
log_puts("\n");
panic();
}
#endif
dev_onmove(f->dev, delta);
}
@ -165,7 +176,7 @@ siofile_play(struct siofile *f)
if (n == 0 && data == base && !sio_eof(f->hdl)) {
siofile_log(f);
log_puts(": write blocked at cycle start, sync error\n");
panic();
/* don't panic since playback might be ahead of recording */
}
if (log_level >= 4) {
siofile_log(f);
@ -295,6 +306,7 @@ siofile_start(struct siofile *f)
f->todo = d->round * d->rchan * d->par.bps;
}
#ifdef DEBUG
f->delay = 0;
f->sum_utime = 0;
f->sum_wtime = 0;
f->wtime = file_wtime;
@ -368,6 +380,9 @@ siofile_run(void *arg)
f->state = STATE_CYCLE;
break;
case STATE_CYCLE:
#ifdef DEBUG
f->delay -= d->round;
#endif
dev_cycle(d);
if (d->mode & MODE_PLAY) {
f->state = STATE_PLAY;

View File

@ -81,7 +81,7 @@
#define DEFAULT_DEV "rsnd/0"
#endif
unsigned int log_level = 1;
unsigned int log_level = 0;
volatile sig_atomic_t quit_flag = 0;
char usagestr[] = "usage: sndiod [-d] [-a flag] [-b nframes] "

View File

@ -877,12 +877,9 @@ sock_hello(struct sock *f)
d = dev_bynum(p->devnum);
if (d == NULL)
return 0;
if (mode & MODE_MIDIOUT)
f->midi->txmask = d->midi->rxmask;
if (mode & MODE_MIDIIN)
d->midi->txmask |= f->midi->rxmask;
midi_tag(f->midi, p->devnum);
} else if (p->devnum < 32) {
midi_tag(f->midi, p->devnum - 16);
midi_tag(f->midi, p->devnum);
} else
return 0;
return 1;