From a3a868da74370890397b3e751c988e716ea0abe7 Mon Sep 17 00:00:00 2001 From: Alexandre Ratchov Date: Wed, 7 Nov 2012 08:48:35 +0100 Subject: [PATCH] prime buffers with silence; make flow control start with zero maxwrite --- aucat/sock.c | 7 ++-- libsndio/amsg.h | 2 +- libsndio/sio_aucat.c | 2 +- sndiod/defs.h | 2 +- sndiod/dev.c | 23 ++++++++++--- sndiod/sock.c | 78 ++++++++++++++++++++++++++++++++------------ 6 files changed, 83 insertions(+), 31 deletions(-) diff --git a/aucat/sock.c b/aucat/sock.c index ebef0d1..be089cf 100644 --- a/aucat/sock.c +++ b/aucat/sock.c @@ -398,7 +398,8 @@ sock_allocbuf(struct sock *f) aproc_setout(f->pipe.file.rproc, rbuf); if (!ABUF_WOK(rbuf) || (f->pipe.file.state & FILE_EOF)) f->pstate = SOCK_READY; - f->rmax = bufsz * aparams_bpf(&f->rpar); + f->fillpending = bufsz; + f->rmax = 0; } if (f->mode & MODE_RECMASK) { wbuf = abuf_new(bufsz, &f->wpar); @@ -408,7 +409,6 @@ sock_allocbuf(struct sock *f) } f->delta = 0; f->tickpending = 0; - f->fillpending = 0; #ifdef DEBUG if (debug_level >= 3) { sock_dbg(f); @@ -551,13 +551,14 @@ sock_attach(struct sock *f, int force) */ f->delta = dev_getpos(f->dev) * (int)f->round / (int)f->dev->round; - f->fillpending = 0; f->pstate = SOCK_RUN; #ifdef DEBUG if (debug_level >= 3) { sock_dbg(f); dbg_puts(": attaching at "); dbg_puti(f->delta); + dbg_puts("fillpending = "); + dbg_puti(f->fillpending); dbg_puts("\n"); } #endif diff --git a/libsndio/amsg.h b/libsndio/amsg.h index 1b85e19..0b3c2e9 100644 --- a/libsndio/amsg.h +++ b/libsndio/amsg.h @@ -80,7 +80,7 @@ struct amsg { } vol; struct amsg_hello { uint16_t mode; /* bitmap of MODE_XXX */ -#define AMSG_VERSION 6 +#define AMSG_VERSION 7 uint8_t version; /* protocol version */ uint8_t devnum; /* device number */ uint32_t _reserved[1]; /* for future use */ diff --git a/libsndio/sio_aucat.c b/libsndio/sio_aucat.c index 7ebda76..cc58aff 100644 --- a/libsndio/sio_aucat.c +++ b/libsndio/sio_aucat.c @@ -190,7 +190,7 @@ sio_aucat_start(struct sio_hdl *sh) return 0; hdl->wbpf = par.bps * par.pchan; hdl->rbpf = par.bps * par.rchan; - hdl->aucat.maxwrite = hdl->wbpf * par.bufsz; + hdl->aucat.maxwrite = 0; hdl->round = par.round; hdl->delta = 0; DPRINTF("aucat: start, maxwrite = %d\n", hdl->aucat.maxwrite); diff --git a/sndiod/defs.h b/sndiod/defs.h index 7fc782b..62101c5 100644 --- a/sndiod/defs.h +++ b/sndiod/defs.h @@ -31,7 +31,7 @@ extern unsigned int log_level; /* * 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. diff --git a/sndiod/dev.c b/sndiod/dev.c index 45f12b8..ace9b67 100644 --- a/sndiod/dev.c +++ b/sndiod/dev.c @@ -622,6 +622,21 @@ dev_mix_badd(struct dev *d, struct slot *s) 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 dev_mix_cycle(struct dev *d) { @@ -954,7 +969,7 @@ dev_cycle(struct dev *d) #endif if (d->prime > 0) { d->prime -= d->round; - dev_mix_cycle(d); + dev_empty_cycle(d); } else { if (d->mode & MODE_RECMASK) dev_sub_cycle(d); @@ -969,7 +984,7 @@ dev_cycle(struct dev *d) int 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(); } #endif - bufsz = SLOT_BUFSZ(s); + bufsz = s->appbufsz; if (s->mode & MODE_PLAY) { #ifdef DEBUG if (log_level >= 3) { @@ -1865,7 +1880,7 @@ slot_start(struct slot *s) log_puts(": allocated "); log_putu(s->appbufsz); log_puts("/"); - log_putu(bufsz); + log_putu(SLOT_BUFSZ(s)); log_puts(" fr buffers\n"); } #endif diff --git a/sndiod/sock.c b/sndiod/sock.c index c3d2110..172596d 100644 --- a/sndiod/sock.c +++ b/sndiod/sock.c @@ -176,8 +176,8 @@ sock_slot_fill(void *arg) log_puts("\n"); } #endif - while (sock_write(f)) - ; + if (f->wstate == SOCK_WIDLE && f->rstate != SOCK_RRET) + sock_buildmsg(f); } void @@ -195,8 +195,8 @@ sock_slot_flush(void *arg) log_puts("\n"); } #endif - while (sock_write(f)) - ; + if (f->wstate == SOCK_WIDLE && f->rstate != SOCK_RRET) + sock_buildmsg(f); } void @@ -211,8 +211,8 @@ sock_slot_eof(void *arg) } #endif f->stoppending = 1; - while (sock_write(f)) - ; + if (f->wstate == SOCK_WIDLE && f->rstate != SOCK_RRET) + sock_buildmsg(f); } void @@ -232,8 +232,8 @@ sock_slot_onmove(void *arg, int delta) if (s->pstate != SOCK_START) return; f->tickpending++; - while (sock_write(f)) - ; + if (f->wstate == SOCK_WIDLE && f->rstate != SOCK_RRET) + sock_buildmsg(f); } void @@ -252,8 +252,8 @@ sock_slot_onvol(void *arg, unsigned int delta) #endif if (s->pstate != SOCK_START) return; - while (sock_write(f)) - ; + if (f->wstate == SOCK_WIDLE && f->rstate != SOCK_RRET) + sock_buildmsg(f); } void @@ -270,8 +270,8 @@ sock_midi_omsg(void *arg, unsigned char *msg, int size) struct sock *f = arg; midi_out(f->midi, msg, size); - while (sock_write(f)) - ; + if (f->wstate == SOCK_WIDLE && f->rstate != SOCK_RRET) + sock_buildmsg(f); } void @@ -280,8 +280,8 @@ sock_midi_fill(void *arg, int count) struct sock *f = arg; 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"); } sock_close(f); + } else { +#ifdef DEBUG + if (log_level >= 4) { + sock_log(f); + log_puts(": write blocked\n"); + } +#endif } return 0; } @@ -431,6 +438,13 @@ sock_fdread(struct sock *f, void *data, int count) log_puts("\n"); } sock_close(f); + } else { +#ifdef DEBUG + if (log_level >= 4) { + sock_log(f); + log_puts(": read blocked\n"); + } +#endif } return 0; } @@ -998,6 +1012,16 @@ sock_execmsg(struct sock *f) return 0; } 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) { #ifdef DEBUG if (log_level >= 1) { @@ -1008,6 +1032,8 @@ sock_execmsg(struct sock *f) sock_close(f); return 0; } + if (f->ralign == 0) + f->ralign = s->round * s->mix.bpf; if (s != NULL && size > f->ralign) { #ifdef DEBUG if (log_level >= 1) { @@ -1026,8 +1052,6 @@ sock_execmsg(struct sock *f) f->rsize = f->rtodo = size; if (s != NULL) { f->ralign -= size; - if (f->ralign == 0) - f->ralign = s->round * s->mix.bpf; } if (f->rtodo > f->rmax) { #ifdef DEBUG @@ -1076,10 +1100,9 @@ sock_execmsg(struct sock *f) f->stoppending = 0; slot_start(s); if (s->mode & MODE_PLAY) { - f->fillpending = -(int)s->dev->bufsz * - (int)s->round / (int)s->dev->round; - f->ralign = s->round * s->mix.bpf; - f->rmax = SLOT_BUFSZ(s) * s->mix.bpf; + f->fillpending = s->appbufsz; + f->ralign = 0; + f->rmax = 0; } if (s->mode & MODE_RECMASK) { f->walign = s->round * s->sub.bpf; @@ -1141,7 +1164,11 @@ sock_execmsg(struct sock *f) #ifdef DEBUG if (size < f->ralign) { 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(); } #endif @@ -1606,9 +1633,18 @@ sock_write(struct sock *f) log_puts(": copied RRET message\n"); } #endif + /* + * XXX: + * the rule is to not mix read code paths and + * write code paths + */ while (sock_read(f)) ; } + /* + * XXX: if sock_read blocks, we end-up here in + * the WMSG state + */ if (!sock_buildmsg(f)) return 0; break;