prime buffers with silence; make flow control start with zero

maxwrite
This commit is contained in:
Alexandre Ratchov 2012-11-07 08:48:35 +01:00
parent d6cb8d427d
commit a3a868da74
6 changed files with 83 additions and 31 deletions

View File

@ -398,7 +398,8 @@ sock_allocbuf(struct sock *f)
aproc_setout(f->pipe.file.rproc, rbuf); aproc_setout(f->pipe.file.rproc, rbuf);
if (!ABUF_WOK(rbuf) || (f->pipe.file.state & FILE_EOF)) if (!ABUF_WOK(rbuf) || (f->pipe.file.state & FILE_EOF))
f->pstate = SOCK_READY; f->pstate = SOCK_READY;
f->rmax = bufsz * aparams_bpf(&f->rpar); f->fillpending = bufsz;
f->rmax = 0;
} }
if (f->mode & MODE_RECMASK) { if (f->mode & MODE_RECMASK) {
wbuf = abuf_new(bufsz, &f->wpar); wbuf = abuf_new(bufsz, &f->wpar);
@ -408,7 +409,6 @@ sock_allocbuf(struct sock *f)
} }
f->delta = 0; f->delta = 0;
f->tickpending = 0; f->tickpending = 0;
f->fillpending = 0;
#ifdef DEBUG #ifdef DEBUG
if (debug_level >= 3) { if (debug_level >= 3) {
sock_dbg(f); sock_dbg(f);
@ -551,13 +551,14 @@ sock_attach(struct sock *f, int force)
*/ */
f->delta = dev_getpos(f->dev) * f->delta = dev_getpos(f->dev) *
(int)f->round / (int)f->dev->round; (int)f->round / (int)f->dev->round;
f->fillpending = 0;
f->pstate = SOCK_RUN; f->pstate = SOCK_RUN;
#ifdef DEBUG #ifdef DEBUG
if (debug_level >= 3) { if (debug_level >= 3) {
sock_dbg(f); sock_dbg(f);
dbg_puts(": attaching at "); dbg_puts(": attaching at ");
dbg_puti(f->delta); dbg_puti(f->delta);
dbg_puts("fillpending = ");
dbg_puti(f->fillpending);
dbg_puts("\n"); dbg_puts("\n");
} }
#endif #endif

View File

@ -80,7 +80,7 @@ struct amsg {
} vol; } vol;
struct amsg_hello { struct amsg_hello {
uint16_t mode; /* bitmap of MODE_XXX */ uint16_t mode; /* bitmap of MODE_XXX */
#define AMSG_VERSION 6 #define AMSG_VERSION 7
uint8_t version; /* protocol version */ uint8_t version; /* protocol version */
uint8_t devnum; /* device number */ uint8_t devnum; /* device number */
uint32_t _reserved[1]; /* for future use */ uint32_t _reserved[1]; /* for future use */

View File

@ -190,7 +190,7 @@ sio_aucat_start(struct sio_hdl *sh)
return 0; return 0;
hdl->wbpf = par.bps * par.pchan; hdl->wbpf = par.bps * par.pchan;
hdl->rbpf = par.bps * par.rchan; hdl->rbpf = par.bps * par.rchan;
hdl->aucat.maxwrite = hdl->wbpf * par.bufsz; hdl->aucat.maxwrite = 0;
hdl->round = par.round; hdl->round = par.round;
hdl->delta = 0; hdl->delta = 0;
DPRINTF("aucat: start, maxwrite = %d\n", hdl->aucat.maxwrite); DPRINTF("aucat: start, maxwrite = %d\n", hdl->aucat.maxwrite);

View File

@ -31,7 +31,7 @@ extern unsigned int log_level;
/* /*
* MIDI buffer size * MIDI buffer size
*/ */
#define MIDI_BUFSZ 15 /* 1 second at 31.25kbit/s */ #define MIDI_BUFSZ 3125 /* 1 second at 31.25kbit/s */
/* /*
* units used for MTC clock. * units used for MTC clock.

View File

@ -622,6 +622,21 @@ dev_mix_badd(struct dev *d, struct slot *s)
abuf_rdiscard(&s->mix.buf, s->round * s->mix.bpf); abuf_rdiscard(&s->mix.buf, s->round * s->mix.bpf);
} }
void
dev_empty_cycle(struct dev *d)
{
unsigned char *base;
int nsamp;
base = (unsigned char *)DEV_PBUF(d);
nsamp = d->round * d->pchan;
memset(base, 0, nsamp * sizeof(adata_t));
if (d->encbuf) {
enc_do(&d->enc, (unsigned char *)DEV_PBUF(d),
d->encbuf, d->round);
}
}
void void
dev_mix_cycle(struct dev *d) dev_mix_cycle(struct dev *d)
{ {
@ -954,7 +969,7 @@ dev_cycle(struct dev *d)
#endif #endif
if (d->prime > 0) { if (d->prime > 0) {
d->prime -= d->round; d->prime -= d->round;
dev_mix_cycle(d); dev_empty_cycle(d);
} else { } else {
if (d->mode & MODE_RECMASK) if (d->mode & MODE_RECMASK)
dev_sub_cycle(d); dev_sub_cycle(d);
@ -969,7 +984,7 @@ dev_cycle(struct dev *d)
int int
dev_getpos(struct dev *d) dev_getpos(struct dev *d)
{ {
return (d->mode & MODE_PLAY) ? -(d->bufsz - d->prime) : 0; return (d->mode & MODE_PLAY) ? -d->bufsz : 0;
} }
/* /*
@ -1827,7 +1842,7 @@ slot_start(struct slot *s)
panic(); panic();
} }
#endif #endif
bufsz = SLOT_BUFSZ(s); bufsz = s->appbufsz;
if (s->mode & MODE_PLAY) { if (s->mode & MODE_PLAY) {
#ifdef DEBUG #ifdef DEBUG
if (log_level >= 3) { if (log_level >= 3) {
@ -1865,7 +1880,7 @@ slot_start(struct slot *s)
log_puts(": allocated "); log_puts(": allocated ");
log_putu(s->appbufsz); log_putu(s->appbufsz);
log_puts("/"); log_puts("/");
log_putu(bufsz); log_putu(SLOT_BUFSZ(s));
log_puts(" fr buffers\n"); log_puts(" fr buffers\n");
} }
#endif #endif

View File

@ -176,8 +176,8 @@ sock_slot_fill(void *arg)
log_puts("\n"); log_puts("\n");
} }
#endif #endif
while (sock_write(f)) if (f->wstate == SOCK_WIDLE && f->rstate != SOCK_RRET)
; sock_buildmsg(f);
} }
void void
@ -195,8 +195,8 @@ sock_slot_flush(void *arg)
log_puts("\n"); log_puts("\n");
} }
#endif #endif
while (sock_write(f)) if (f->wstate == SOCK_WIDLE && f->rstate != SOCK_RRET)
; sock_buildmsg(f);
} }
void void
@ -211,8 +211,8 @@ sock_slot_eof(void *arg)
} }
#endif #endif
f->stoppending = 1; f->stoppending = 1;
while (sock_write(f)) if (f->wstate == SOCK_WIDLE && f->rstate != SOCK_RRET)
; sock_buildmsg(f);
} }
void void
@ -232,8 +232,8 @@ sock_slot_onmove(void *arg, int delta)
if (s->pstate != SOCK_START) if (s->pstate != SOCK_START)
return; return;
f->tickpending++; f->tickpending++;
while (sock_write(f)) if (f->wstate == SOCK_WIDLE && f->rstate != SOCK_RRET)
; sock_buildmsg(f);
} }
void void
@ -252,8 +252,8 @@ sock_slot_onvol(void *arg, unsigned int delta)
#endif #endif
if (s->pstate != SOCK_START) if (s->pstate != SOCK_START)
return; return;
while (sock_write(f)) if (f->wstate == SOCK_WIDLE && f->rstate != SOCK_RRET)
; sock_buildmsg(f);
} }
void void
@ -270,8 +270,8 @@ sock_midi_omsg(void *arg, unsigned char *msg, int size)
struct sock *f = arg; struct sock *f = arg;
midi_out(f->midi, msg, size); midi_out(f->midi, msg, size);
while (sock_write(f)) if (f->wstate == SOCK_WIDLE && f->rstate != SOCK_RRET)
; sock_buildmsg(f);
} }
void void
@ -280,8 +280,8 @@ sock_midi_fill(void *arg, int count)
struct sock *f = arg; struct sock *f = arg;
f->fillpending += count; f->fillpending += count;
while (sock_write(f)) if (f->wstate == SOCK_WIDLE && f->rstate != SOCK_RRET)
; sock_buildmsg(f);
} }
/* /*
@ -402,6 +402,13 @@ sock_fdwrite(struct sock *f, void *data, int count)
log_puts("\n"); log_puts("\n");
} }
sock_close(f); sock_close(f);
} else {
#ifdef DEBUG
if (log_level >= 4) {
sock_log(f);
log_puts(": write blocked\n");
}
#endif
} }
return 0; return 0;
} }
@ -431,6 +438,13 @@ sock_fdread(struct sock *f, void *data, int count)
log_puts("\n"); log_puts("\n");
} }
sock_close(f); sock_close(f);
} else {
#ifdef DEBUG
if (log_level >= 4) {
sock_log(f);
log_puts(": read blocked\n");
}
#endif
} }
return 0; return 0;
} }
@ -998,6 +1012,16 @@ sock_execmsg(struct sock *f)
return 0; return 0;
} }
size = ntohl(m->u.data.size); size = ntohl(m->u.data.size);
if (size == 0) {
#ifdef DEBUG
if (log_level >= 1) {
sock_log(f);
log_puts(": zero size payload\n");
}
#endif
sock_close(f);
return 0;
}
if (s != NULL && size % s->mix.bpf != 0) { if (s != NULL && size % s->mix.bpf != 0) {
#ifdef DEBUG #ifdef DEBUG
if (log_level >= 1) { if (log_level >= 1) {
@ -1008,6 +1032,8 @@ sock_execmsg(struct sock *f)
sock_close(f); sock_close(f);
return 0; return 0;
} }
if (f->ralign == 0)
f->ralign = s->round * s->mix.bpf;
if (s != NULL && size > f->ralign) { if (s != NULL && size > f->ralign) {
#ifdef DEBUG #ifdef DEBUG
if (log_level >= 1) { if (log_level >= 1) {
@ -1026,8 +1052,6 @@ sock_execmsg(struct sock *f)
f->rsize = f->rtodo = size; f->rsize = f->rtodo = size;
if (s != NULL) { if (s != NULL) {
f->ralign -= size; f->ralign -= size;
if (f->ralign == 0)
f->ralign = s->round * s->mix.bpf;
} }
if (f->rtodo > f->rmax) { if (f->rtodo > f->rmax) {
#ifdef DEBUG #ifdef DEBUG
@ -1076,10 +1100,9 @@ sock_execmsg(struct sock *f)
f->stoppending = 0; f->stoppending = 0;
slot_start(s); slot_start(s);
if (s->mode & MODE_PLAY) { if (s->mode & MODE_PLAY) {
f->fillpending = -(int)s->dev->bufsz * f->fillpending = s->appbufsz;
(int)s->round / (int)s->dev->round; f->ralign = 0;
f->ralign = s->round * s->mix.bpf; f->rmax = 0;
f->rmax = SLOT_BUFSZ(s) * s->mix.bpf;
} }
if (s->mode & MODE_RECMASK) { if (s->mode & MODE_RECMASK) {
f->walign = s->round * s->sub.bpf; f->walign = s->round * s->sub.bpf;
@ -1141,7 +1164,11 @@ sock_execmsg(struct sock *f)
#ifdef DEBUG #ifdef DEBUG
if (size < f->ralign) { if (size < f->ralign) {
sock_log(f); sock_log(f);
log_puts(": unaligned stop\n"); log_puts(": unaligned stop, size = ");
log_putu(size);
log_puts(", ralign = ");
log_putu(f->ralign);
log_puts("\n");
panic(); panic();
} }
#endif #endif
@ -1606,9 +1633,18 @@ sock_write(struct sock *f)
log_puts(": copied RRET message\n"); log_puts(": copied RRET message\n");
} }
#endif #endif
/*
* XXX:
* the rule is to not mix read code paths and
* write code paths
*/
while (sock_read(f)) while (sock_read(f))
; ;
} }
/*
* XXX: if sock_read blocks, we end-up here in
* the WMSG state
*/
if (!sock_buildmsg(f)) if (!sock_buildmsg(f))
return 0; return 0;
break; break;