make abuf structure use bytes

This commit is contained in:
Alexandre Ratchov 2012-11-02 19:05:29 +01:00
parent f2c1c70165
commit 5fddbed369
6 changed files with 63 additions and 42 deletions

View File

@ -43,11 +43,10 @@ abuf_log(struct abuf *buf)
#endif #endif
void void
abuf_init(struct abuf *buf, unsigned int len, unsigned int bpf) abuf_init(struct abuf *buf, unsigned int len)
{ {
buf->data = xmalloc((size_t)len * bpf); buf->data = xmalloc(len);
buf->len = len; buf->len = len;
buf->bpf = bpf;
buf->used = 0; buf->used = 0;
buf->start = 0; buf->start = 0;
} }
@ -80,7 +79,7 @@ abuf_rgetblk(struct abuf *buf, int *rsize)
if (count > buf->used) if (count > buf->used)
count = buf->used; count = buf->used;
*rsize = count; *rsize = count;
return buf->data + buf->start * buf->bpf; return buf->data + buf->start;
} }
/* /*
@ -136,5 +135,5 @@ abuf_wgetblk(struct abuf *buf, int *rsize)
if (count > avail) if (count > avail)
count = avail; count = avail;
*rsize = count; *rsize = count;
return buf->data + end * buf->bpf; return buf->data + end;
} }

View File

@ -18,14 +18,13 @@
#define ABUF_H #define ABUF_H
struct abuf { struct abuf {
int bpf; /* bytes per frames */
int start; /* offset (frames) where stored data starts */ int start; /* offset (frames) where stored data starts */
int used; /* frames stored in the buffer */ int used; /* frames stored in the buffer */
int len; /* total size of the buffer (frames) */ int len; /* total size of the buffer (frames) */
unsigned char *data; unsigned char *data;
}; };
void abuf_init(struct abuf *, unsigned int, unsigned int); void abuf_init(struct abuf *, unsigned int);
void abuf_done(struct abuf *); void abuf_done(struct abuf *);
void abuf_log(struct abuf *); void abuf_log(struct abuf *);
unsigned char *abuf_rgetblk(struct abuf *, int *); unsigned char *abuf_rgetblk(struct abuf *, int *);

View File

@ -481,14 +481,14 @@ dev_midi_exit(void *arg)
void void
slot_mix_drop(struct slot *s) slot_mix_drop(struct slot *s)
{ {
while (s->mix.drop > 0 && s->mix.buf.used >= s->round) { while (s->mix.drop > 0 && s->mix.buf.used >= s->round * s->mix.bpf) {
#ifdef DEBUG #ifdef DEBUG
if (log_level >= 4) { if (log_level >= 4) {
slot_log(s); slot_log(s);
log_puts(": dropped a play block\n"); log_puts(": dropped a play block\n");
} }
#endif #endif
abuf_rdiscard(&s->mix.buf, s->round); abuf_rdiscard(&s->mix.buf, s->round * s->mix.bpf);
s->mix.drop--; s->mix.drop--;
} }
} }
@ -501,7 +501,7 @@ slot_sub_sil(struct slot *s)
while (s->sub.silence > 0) { while (s->sub.silence > 0) {
data = abuf_wgetblk(&s->sub.buf, &count); data = abuf_wgetblk(&s->sub.buf, &count);
if (count < s->round) if (count < s->round * s->sub.bpf)
break; break;
#ifdef DEBUG #ifdef DEBUG
if (log_level >= 4) { if (log_level >= 4) {
@ -512,8 +512,8 @@ slot_sub_sil(struct slot *s)
if (s->sub.encbuf) if (s->sub.encbuf)
enc_sil_do(&s->sub.enc, data, s->round); enc_sil_do(&s->sub.enc, data, s->round);
else else
memset(data, 0, s->round * s->sub.buf.bpf); memset(data, 0, s->round * s->sub.bpf);
abuf_wcommit(&s->sub.buf, s->round); abuf_wcommit(&s->sub.buf, s->round * s->sub.bpf);
s->sub.silence--; s->sub.silence--;
} }
} }
@ -594,20 +594,18 @@ dev_mix_badd(struct dev *d, struct slot *s)
odata = DEV_PBUF(d); odata = DEV_PBUF(d);
idata = (adata_t *)abuf_rgetblk(&s->mix.buf, &icount); idata = (adata_t *)abuf_rgetblk(&s->mix.buf, &icount);
#ifdef DEBUG #ifdef DEBUG
if (icount < s->round && s->pstate != SLOT_STOP) { if (icount < s->round * s->mix.bpf) {
slot_log(s); slot_log(s);
log_puts(": not enough data to mix ("); log_puts(": not enough data to mix (");
log_putu(icount); log_putu(icount);
log_puts(" of "); log_puts(" of ");
log_putu(d->round); log_putu(d->round * s->mix.bpf);
log_puts(")\n"); log_puts(")\n");
panic(); panic();
} }
#endif #endif
if (icount > s->round) play_filt_dec(s, idata, odata, s->round);
icount = s->round; abuf_rdiscard(&s->mix.buf, s->round * s->mix.bpf);
play_filt_dec(s, idata, odata, icount);
abuf_rdiscard(&s->mix.buf, icount);
} }
void void
@ -649,7 +647,12 @@ dev_mix_cycle(struct dev *d)
ps = &s->next; ps = &s->next;
continue; continue;
} }
if (s->pstate == SLOT_STOP && s->mix.buf.used == 0) { if (s->mix.buf.used < s->round * s->mix.bpf &&
s->pstate == SLOT_STOP) {
/*
* partial blocks are zero-filled by socket
* layer
*/
s->pstate = SLOT_INIT; s->pstate = SLOT_INIT;
abuf_done(&s->mix.buf); abuf_done(&s->mix.buf);
if (s->mix.decbuf) if (s->mix.decbuf)
@ -660,7 +663,8 @@ dev_mix_cycle(struct dev *d)
*ps = s->next; *ps = s->next;
continue; continue;
} }
if (s->mix.buf.used < s->round && !(s->pstate == SLOT_STOP)) { if (s->mix.buf.used < s->round * s->mix.bpf &&
!(s->pstate == SLOT_STOP)) {
if (s->xrun == XRUN_IGNORE) { if (s->xrun == XRUN_IGNORE) {
if (s->mode & MODE_RECMASK) if (s->mode & MODE_RECMASK)
s->sub.silence--; s->sub.silence--;
@ -803,13 +807,13 @@ dev_sub_bcopy(struct dev *d, struct slot *s)
idata = (s->mode & MODE_MON) ? DEV_PBUF(d) : d->rbuf; idata = (s->mode & MODE_MON) ? DEV_PBUF(d) : d->rbuf;
odata = (adata_t *)abuf_wgetblk(&s->sub.buf, &ocount); odata = (adata_t *)abuf_wgetblk(&s->sub.buf, &ocount);
#ifdef DEBUG #ifdef DEBUG
if (ocount < s->round) { if (ocount < s->round * s->sub.bpf) {
log_puts("dev_sub_bcopy: not enough space\n"); log_puts("dev_sub_bcopy: not enough space\n");
panic(); panic();
} }
#endif #endif
ocount = rec_filt_enc(s, idata, odata, d->round); ocount = rec_filt_enc(s, idata, odata, d->round);
abuf_wcommit(&s->sub.buf, ocount); abuf_wcommit(&s->sub.buf, ocount * s->sub.bpf);
} }
void void
@ -837,7 +841,7 @@ dev_sub_cycle(struct dev *d)
ps = &s->next; ps = &s->next;
continue; continue;
} }
if (s->sub.buf.len - s->sub.buf.used < s->round) { if (s->sub.buf.len - s->sub.buf.used < s->round * s->sub.bpf) {
if (s->xrun == XRUN_IGNORE) { if (s->xrun == XRUN_IGNORE) {
if (s->mode & MODE_PLAY) if (s->mode & MODE_PLAY)
s->mix.drop--; s->mix.drop--;
@ -1812,8 +1816,9 @@ slot_start(struct slot *s)
log_puts("\n"); log_puts("\n");
} }
#endif #endif
abuf_init(&s->mix.buf, bufsz, s->mix.bpf = s->par.bps *
s->par.bps * (s->mix.slot_cmax - s->mix.slot_cmin + 1)); (s->mix.slot_cmax - s->mix.slot_cmin + 1);
abuf_init(&s->mix.buf, bufsz * s->mix.bpf);
} }
if (s->mode & MODE_RECMASK) { if (s->mode & MODE_RECMASK) {
#ifdef DEBUG #ifdef DEBUG
@ -1826,8 +1831,9 @@ slot_start(struct slot *s)
log_puts("\n"); log_puts("\n");
} }
#endif #endif
abuf_init(&s->sub.buf, bufsz, s->sub.bpf = s->par.bps *
s->par.bps * (s->sub.slot_cmax - s->sub.slot_cmin + 1)); (s->sub.slot_cmax - s->sub.slot_cmin + 1);
abuf_init(&s->sub.buf, bufsz * s->sub.bpf);
} }
s->mix.weight = MIDI_TO_ADATA(MIDI_MAXCTL); s->mix.weight = MIDI_TO_ADATA(MIDI_MAXCTL);
#ifdef DEBUG #ifdef DEBUG

View File

@ -53,6 +53,7 @@ struct slot {
unsigned int vol; /* volume within the vol */ unsigned int vol; /* volume within the vol */
int drop; /* to drop on next read */ int drop; /* to drop on next read */
struct abuf buf; /* socket side buffer */ struct abuf buf; /* socket side buffer */
int bpf; /* byte per frame */
int slot_cmin, slot_cmax; /* slot source chans */ int slot_cmin, slot_cmax; /* slot source chans */
int dev_cmin, dev_cmax; /* device destination chans */ int dev_cmin, dev_cmax; /* device destination chans */
struct cmap cmap; /* channel mapper state */ struct cmap cmap; /* channel mapper state */
@ -65,6 +66,7 @@ struct slot {
struct { struct {
int silence; /* to add on next write */ int silence; /* to add on next write */
struct abuf buf; /* socket side buffer */ struct abuf buf; /* socket side buffer */
int bpf; /* byte per frame */
int slot_cmin, slot_cmax; /* slot destination chans */ int slot_cmin, slot_cmax; /* slot destination chans */
int dev_cmin, dev_cmax; /* device source chans */ int dev_cmin, dev_cmax; /* device source chans */
struct cmap cmap; /* channel mapper state */ struct cmap cmap; /* channel mapper state */

View File

@ -130,10 +130,10 @@ midi_new(struct midiops *ops, void *arg, int mode)
* to client input * to client input
*/ */
if (ep->mode & MODE_MIDIOUT) { if (ep->mode & MODE_MIDIOUT) {
abuf_init(&ep->ibuf, MIDI_BUFSZ, 1); abuf_init(&ep->ibuf, MIDI_BUFSZ);
} }
if (ep->mode & MODE_MIDIIN) { if (ep->mode & MODE_MIDIIN) {
abuf_init(&ep->obuf, MIDI_BUFSZ, 1); abuf_init(&ep->obuf, MIDI_BUFSZ);
} }
return ep; return ep;
} }

View File

@ -184,7 +184,7 @@ sock_slot_flush(void *arg)
struct sock *f = arg; struct sock *f = arg;
struct slot *s = f->slot; struct slot *s = f->slot;
f->wmax += s->round * s->sub.buf.bpf; f->wmax += s->round * s->sub.bpf;
#ifdef DEBUG #ifdef DEBUG
if (log_level >= 4) { if (log_level >= 4) {
sock_log(f); sock_log(f);
@ -527,7 +527,7 @@ sock_rdata(struct sock *f)
* XXX: this can happen in MIDIOUT mode, since we dont * XXX: this can happen in MIDIOUT mode, since we dont
* have flow control * have flow control
*/ */
if (count * buf->bpf < f->rtodo) { if (count < f->rtodo) {
sock_log(f); sock_log(f);
log_puts(": data read buffer overrun\n"); log_puts(": data read buffer overrun\n");
panic(); panic();
@ -545,7 +545,7 @@ sock_rdata(struct sock *f)
* XXX: commit data earlier, don't sacrify a full block in case * XXX: commit data earlier, don't sacrify a full block in case
* of xrun * of xrun
*/ */
abuf_wcommit(buf, f->rsize / buf->bpf); abuf_wcommit(buf, f->rsize);
f->rtodo = 0; f->rtodo = 0;
#ifdef DEBUG #ifdef DEBUG
if (log_level >= 4) { if (log_level >= 4) {
@ -611,7 +611,7 @@ sock_wdata(struct sock *f)
return 0; return 0;
} }
if (f->pstate != SOCK_STOP) { if (f->pstate != SOCK_STOP) {
abuf_rdiscard(buf, f->wsize / buf->bpf); abuf_rdiscard(buf, f->wsize);
if (f->slot) if (f->slot)
slot_read(f->slot); slot_read(f->slot);
} }
@ -960,6 +960,7 @@ sock_execmsg(struct sock *f)
struct slot *s = f->slot; struct slot *s = f->slot;
struct amsg *m = &f->rmsg; struct amsg *m = &f->rmsg;
unsigned int size, ctl; unsigned int size, ctl;
unsigned char *data;
switch (ntohl(m->cmd)) { switch (ntohl(m->cmd)) {
case AMSG_DATA: case AMSG_DATA:
@ -991,7 +992,7 @@ sock_execmsg(struct sock *f)
return 0; return 0;
} }
size = ntohl(m->u.data.size); size = ntohl(m->u.data.size);
if (s != NULL && size % s->mix.buf.bpf != 0) { if (s != NULL && size % s->mix.bpf != 0) {
#ifdef DEBUG #ifdef DEBUG
if (log_level >= 1) { if (log_level >= 1) {
sock_log(f); sock_log(f);
@ -1020,7 +1021,7 @@ sock_execmsg(struct sock *f)
if (s != NULL) { if (s != NULL) {
f->ralign -= size; f->ralign -= size;
if (f->ralign == 0) if (f->ralign == 0)
f->ralign = s->round * s->mix.buf.bpf; f->ralign = s->round * s->mix.bpf;
} }
if (f->rtodo > f->rmax) { if (f->rtodo > f->rmax) {
#ifdef DEBUG #ifdef DEBUG
@ -1071,11 +1072,11 @@ sock_execmsg(struct sock *f)
if (s->mode & MODE_PLAY) { if (s->mode & MODE_PLAY) {
f->fillpending = -(int)s->dev->bufsz * f->fillpending = -(int)s->dev->bufsz *
(int)s->round / (int)s->dev->round; (int)s->round / (int)s->dev->round;
f->ralign = s->round * s->mix.buf.bpf; f->ralign = s->round * s->mix.bpf;
f->rmax = SLOT_BUFSZ(s) * s->mix.buf.bpf; f->rmax = SLOT_BUFSZ(s) * s->mix.bpf;
} }
if (s->mode & MODE_RECMASK) { if (s->mode & MODE_RECMASK) {
f->walign = s->round * s->sub.buf.bpf; f->walign = s->round * s->sub.bpf;
f->wmax = 0; f->wmax = 0;
} }
f->pstate = SOCK_START; f->pstate = SOCK_START;
@ -1129,7 +1130,20 @@ sock_execmsg(struct sock *f)
f->pstate = SOCK_STOP; f->pstate = SOCK_STOP;
f->rstate = SOCK_RMSG; f->rstate = SOCK_RMSG;
f->rtodo = sizeof(struct amsg); f->rtodo = sizeof(struct amsg);
slot_stop(s); if (s->mode & MODE_PLAY) {
data = abuf_wgetblk(&s->mix.buf, &size);
#ifdef DEBUG
if (size < f->ralign) {
sock_log(f);
log_puts(": unaligned stop\n");
panic();
}
#endif
memset(data, 0, f->ralign);
abuf_wcommit(&s->mix.buf, f->ralign);
f->ralign = 0;
}
slot_stop(s);
break; break;
case AMSG_SETPAR: case AMSG_SETPAR:
#ifdef DEBUG #ifdef DEBUG
@ -1357,7 +1371,7 @@ sock_buildmsg(struct sock *f)
f->wmsg.u.ts.delta = htonl(f->fillpending); f->wmsg.u.ts.delta = htonl(f->fillpending);
size = f->fillpending; size = f->fillpending;
if (f->slot) if (f->slot)
size *= f->slot->mix.buf.bpf; size *= f->slot->mix.bpf;
f->rmax += size; f->rmax += size;
f->wtodo = sizeof(struct amsg); f->wtodo = sizeof(struct amsg);
f->wstate = SOCK_WMSG; f->wstate = SOCK_WMSG;
@ -1404,7 +1418,8 @@ sock_buildmsg(struct sock *f)
* If data available, build a DATA message. * If data available, build a DATA message.
*/ */
if (f->slot != NULL && f->slot->sub.buf.used > 0 && f->wmax > 0) { if (f->slot != NULL && f->slot->sub.buf.used > 0 && f->wmax > 0) {
size = f->slot->sub.buf.used * f->slot->sub.buf.bpf; /* XXX: round to bpf */
size = f->slot->sub.buf.used;
if (size > AMSG_DATAMAX) if (size > AMSG_DATAMAX)
size = AMSG_DATAMAX; size = AMSG_DATAMAX;
if (size > f->walign) if (size > f->walign)
@ -1421,7 +1436,7 @@ sock_buildmsg(struct sock *f)
f->walign -= size; f->walign -= size;
f->wmax -= size; f->wmax -= size;
if (f->walign == 0) if (f->walign == 0)
f->walign = f->slot->round * f->slot->sub.buf.bpf; f->walign = f->slot->round * f->slot->sub.bpf;
#ifdef DEBUG #ifdef DEBUG
if (log_level >= 4) { if (log_level >= 4) {
sock_log(f); sock_log(f);