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
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->bpf = bpf;
buf->used = 0;
buf->start = 0;
}
@ -80,7 +79,7 @@ abuf_rgetblk(struct abuf *buf, int *rsize)
if (count > buf->used)
count = buf->used;
*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)
count = avail;
*rsize = count;
return buf->data + end * buf->bpf;
return buf->data + end;
}

View File

@ -18,14 +18,13 @@
#define ABUF_H
struct abuf {
int bpf; /* bytes per frames */
int start; /* offset (frames) where stored data starts */
int used; /* frames stored in the buffer */
int len; /* total size of the buffer (frames) */
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_log(struct abuf *);
unsigned char *abuf_rgetblk(struct abuf *, int *);

View File

@ -481,14 +481,14 @@ dev_midi_exit(void *arg)
void
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
if (log_level >= 4) {
slot_log(s);
log_puts(": dropped a play block\n");
}
#endif
abuf_rdiscard(&s->mix.buf, s->round);
abuf_rdiscard(&s->mix.buf, s->round * s->mix.bpf);
s->mix.drop--;
}
}
@ -501,7 +501,7 @@ slot_sub_sil(struct slot *s)
while (s->sub.silence > 0) {
data = abuf_wgetblk(&s->sub.buf, &count);
if (count < s->round)
if (count < s->round * s->sub.bpf)
break;
#ifdef DEBUG
if (log_level >= 4) {
@ -512,8 +512,8 @@ slot_sub_sil(struct slot *s)
if (s->sub.encbuf)
enc_sil_do(&s->sub.enc, data, s->round);
else
memset(data, 0, s->round * s->sub.buf.bpf);
abuf_wcommit(&s->sub.buf, s->round);
memset(data, 0, s->round * s->sub.bpf);
abuf_wcommit(&s->sub.buf, s->round * s->sub.bpf);
s->sub.silence--;
}
}
@ -594,20 +594,18 @@ dev_mix_badd(struct dev *d, struct slot *s)
odata = DEV_PBUF(d);
idata = (adata_t *)abuf_rgetblk(&s->mix.buf, &icount);
#ifdef DEBUG
if (icount < s->round && s->pstate != SLOT_STOP) {
if (icount < s->round * s->mix.bpf) {
slot_log(s);
log_puts(": not enough data to mix (");
log_putu(icount);
log_puts(" of ");
log_putu(d->round);
log_putu(d->round * s->mix.bpf);
log_puts(")\n");
panic();
}
#endif
if (icount > s->round)
icount = s->round;
play_filt_dec(s, idata, odata, icount);
abuf_rdiscard(&s->mix.buf, icount);
play_filt_dec(s, idata, odata, s->round);
abuf_rdiscard(&s->mix.buf, s->round * s->mix.bpf);
}
void
@ -649,7 +647,12 @@ dev_mix_cycle(struct dev *d)
ps = &s->next;
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;
abuf_done(&s->mix.buf);
if (s->mix.decbuf)
@ -660,7 +663,8 @@ dev_mix_cycle(struct dev *d)
*ps = s->next;
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->mode & MODE_RECMASK)
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;
odata = (adata_t *)abuf_wgetblk(&s->sub.buf, &ocount);
#ifdef DEBUG
if (ocount < s->round) {
if (ocount < s->round * s->sub.bpf) {
log_puts("dev_sub_bcopy: not enough space\n");
panic();
}
#endif
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
@ -837,7 +841,7 @@ dev_sub_cycle(struct dev *d)
ps = &s->next;
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->mode & MODE_PLAY)
s->mix.drop--;
@ -1812,8 +1816,9 @@ slot_start(struct slot *s)
log_puts("\n");
}
#endif
abuf_init(&s->mix.buf, bufsz,
s->par.bps * (s->mix.slot_cmax - s->mix.slot_cmin + 1));
s->mix.bpf = s->par.bps *
(s->mix.slot_cmax - s->mix.slot_cmin + 1);
abuf_init(&s->mix.buf, bufsz * s->mix.bpf);
}
if (s->mode & MODE_RECMASK) {
#ifdef DEBUG
@ -1826,8 +1831,9 @@ slot_start(struct slot *s)
log_puts("\n");
}
#endif
abuf_init(&s->sub.buf, bufsz,
s->par.bps * (s->sub.slot_cmax - s->sub.slot_cmin + 1));
s->sub.bpf = s->par.bps *
(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);
#ifdef DEBUG

View File

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

View File

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

View File

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