in siofile, use struct dev directly

This commit is contained in:
Alexandre Ratchov 2012-11-02 13:19:35 +01:00
parent d0d0d0ee32
commit 532e76198c
4 changed files with 138 additions and 158 deletions

View File

@ -917,7 +917,7 @@ dev_cycle(struct dev *d)
dev_log(d); dev_log(d);
log_puts(": device stopped\n"); log_puts(": device stopped\n");
} }
siofile_stop(&d->sio); dev_sio_stop(d);
d->pstate = DEV_INIT; d->pstate = DEV_INIT;
if (d->refcnt == 0) if (d->refcnt == 0)
dev_close(d); dev_close(d);
@ -1039,7 +1039,7 @@ dev_open(struct dev *d)
d->pchan = 2; d->pchan = 2;
if (d->rchan == 0) if (d->rchan == 0)
d->rchan = 2; d->rchan = 2;
if (!siofile_open(&d->sio, d)) { if (!dev_sio_open(d)) {
if (log_level >= 1) { if (log_level >= 1) {
dev_log(d); dev_log(d);
log_puts(": "); log_puts(": ");
@ -1126,7 +1126,7 @@ dev_close(struct dev *d)
s->ops = NULL; s->ops = NULL;
d->slot_list = snext; d->slot_list = snext;
} }
siofile_close(&d->sio); dev_sio_close(d);
if (d->mode & MODE_PLAY) { if (d->mode & MODE_PLAY) {
if (d->encbuf != NULL) if (d->encbuf != NULL)
xfree(d->encbuf); xfree(d->encbuf);
@ -1275,7 +1275,7 @@ dev_wakeup(struct dev *d)
d->prime = 0; d->prime = 0;
} }
d->pstate = DEV_RUN; d->pstate = DEV_RUN;
siofile_start(&d->sio); dev_sio_start(d);
} }
} }

View File

@ -110,7 +110,7 @@ struct dev {
/* /*
* audio device (while opened) * audio device (while opened)
*/ */
struct siofile sio; struct siofile_ sio;
struct aparams par; /* encoding */ struct aparams par; /* encoding */
int pchan, rchan; /* play & rec channels */ int pchan, rchan; /* play & rec channels */
adata_t *rbuf; /* rec buffer */ adata_t *rbuf; /* rec buffer */

View File

@ -31,138 +31,127 @@
#include "siofile.h" #include "siofile.h"
#include "utils.h" #include "utils.h"
int siofile_pollfd(void *, struct pollfd *); int dev_sio_pollfd(void *, struct pollfd *);
int siofile_revents(void *, struct pollfd *); int dev_sio_revents(void *, struct pollfd *);
void siofile_run(void *); void dev_sio_run(void *);
void siofile_hup(void *); void dev_sio_hup(void *);
struct fileops siofile_ops = { struct fileops dev_sio_ops = {
"sio", "sio",
siofile_pollfd, dev_sio_pollfd,
siofile_revents, dev_sio_revents,
siofile_run, dev_sio_run,
siofile_run, dev_sio_run,
siofile_hup dev_sio_hup
}; };
/*
* print device name and cstate
*/
void void
siofile_log(struct siofile *f) dev_sio_onmove(void *arg, int delta)
{ {
dev_log(f->dev); struct dev *d = arg;
}
void
siofile_onmove(void *arg, int delta)
{
struct siofile *f = arg;
#ifdef DEBUG #ifdef DEBUG
if (delta < 0 || delta > (60 * RATE_MAX)) { if (delta < 0 || delta > (60 * RATE_MAX)) {
siofile_log(f); dev_log(d);
log_puts(": "); log_puts(": ");
log_puti(delta); log_puti(delta);
log_puts(": bogus sndio delta"); log_puts(": bogus sndio delta");
panic(); panic();
} }
if (log_level >= 4) { if (log_level >= 4) {
siofile_log(f); dev_log(d);
log_puts(": tick, delta = "); log_puts(": tick, delta = ");
log_puti(delta); log_puti(delta);
log_puts("\n"); log_puts("\n");
} }
f->sum_utime += file_utime - f->utime; d->sio.sum_utime += file_utime - d->sio.utime;
f->sum_wtime += file_wtime - f->wtime; d->sio.sum_wtime += file_wtime - d->sio.wtime;
f->wtime = file_wtime; d->sio.wtime = file_wtime;
f->utime = file_utime; d->sio.utime = file_utime;
if (f->dev->mode & MODE_PLAY) if (d->mode & MODE_PLAY)
f->pused -= delta; d->sio.pused -= delta;
if (f->dev->mode & MODE_REC) if (d->mode & MODE_REC)
f->rused += delta; d->sio.rused += delta;
#endif #endif
dev_onmove(f->dev, delta); dev_onmove(d, delta);
} }
int int
siofile_rec(struct siofile *f) dev_sio_read(struct dev *d)
{ {
struct dev *d = f->dev;
unsigned char *data, *base; unsigned char *data, *base;
unsigned int n; unsigned int n;
#ifdef DEBUG #ifdef DEBUG
if (f->todo == 0) { if (d->sio.todo == 0) {
log_puts("siofile_in: can't read data\n"); log_puts("dev_sio_read: can't read data\n");
panic(); panic();
} }
if (d->prime > 0) { if (d->prime > 0) {
log_puts("siofile_in: unexpected data\n"); log_puts("dev_sio_read: unexpected data\n");
panic(); panic();
} }
#endif #endif
base = d->decbuf ? d->decbuf : (unsigned char *)d->rbuf; base = d->decbuf ? d->decbuf : (unsigned char *)d->rbuf;
data = base + d->rchan * d->round * d->par.bps - f->todo; data = base + d->rchan * d->round * d->par.bps - d->sio.todo;
n = sio_read(f->hdl, data, f->todo); n = sio_read(d->sio.hdl, data, d->sio.todo);
f->todo -= n; d->sio.todo -= n;
#ifdef DEBUG #ifdef DEBUG
if (n == 0 && data == base && !sio_eof(f->hdl)) { if (n == 0 && data == base && !sio_eof(d->sio.hdl)) {
siofile_log(f); dev_log(d);
log_puts(": read blocked at cycle start, sync error\n"); log_puts(": read blocked at cycle start, sync error\n");
/* don't panic since recording is slightly ahead of playback */ /* don't panic since recording is slightly ahead of playback */
} }
if (log_level >= 4) { if (log_level >= 4) {
siofile_log(f); dev_log(d);
log_puts(": read "); log_puts(": read ");
log_putu(n); log_putu(n);
log_puts(": bytes, todo "); log_puts(": bytes, todo ");
log_putu(f->todo); log_putu(d->sio.todo);
log_puts("/"); log_puts("/");
log_putu(d->round * d->rchan * d->par.bps); log_putu(d->round * d->rchan * d->par.bps);
log_puts("\n"); log_puts("\n");
} }
#endif #endif
if (f->todo > 0) if (d->sio.todo > 0)
return 0; return 0;
return 1; return 1;
} }
int int
siofile_play(struct siofile *f) dev_sio_write(struct dev *d)
{ {
struct dev *d = f->dev;
unsigned char *data, *base; unsigned char *data, *base;
unsigned int n; unsigned int n;
#ifdef DEBUG #ifdef DEBUG
if (f->todo == 0) { if (d->sio.todo == 0) {
log_puts("siofile_in: can't write data\n"); log_puts("dev_sio_write: can't write data\n");
panic(); panic();
} }
#endif #endif
base = d->encbuf ? d->encbuf : (unsigned char *)DEV_PBUF(d); base = d->encbuf ? d->encbuf : (unsigned char *)DEV_PBUF(d);
data = base + d->pchan * d->round * d->par.bps - f->todo; data = base + d->pchan * d->round * d->par.bps - d->sio.todo;
n = sio_write(f->hdl, data, f->todo); n = sio_write(d->sio.hdl, data, d->sio.todo);
f->todo -= n; d->sio.todo -= n;
#ifdef DEBUG #ifdef DEBUG
if (n == 0 && data == base && !sio_eof(f->hdl)) { if (n == 0 && data == base && !sio_eof(d->sio.hdl)) {
siofile_log(f); dev_log(d);
log_puts(": write blocked at cycle start, sync error\n"); log_puts(": write blocked at cycle start, sync error\n");
/* don't panic since playback might be ahead of recording */ /* don't panic since playback might be ahead of recording */
} }
if (log_level >= 4) { if (log_level >= 4) {
siofile_log(f); dev_log(d);
log_puts(": wrote "); log_puts(": wrote ");
log_putu(n); log_putu(n);
log_puts(" bytes, todo "); log_puts(" bytes, todo ");
log_putu(f->todo); log_putu(d->sio.todo);
log_puts("/"); log_puts("/");
log_putu(d->round * d->pchan * d->par.bps); log_putu(d->round * d->pchan * d->par.bps);
log_puts("\n"); log_puts("\n");
} }
#endif #endif
if (f->todo > 0) if (d->sio.todo > 0)
return 0; return 0;
return 1; return 1;
} }
@ -171,21 +160,21 @@ siofile_play(struct siofile *f)
* open the device. * open the device.
*/ */
int int
siofile_open(struct siofile *f, struct dev *d) dev_sio_open(struct dev *d)
{ {
struct sio_par par; struct sio_par par;
unsigned int mode = d->mode & (MODE_PLAY | MODE_REC); unsigned int mode = d->mode & (MODE_PLAY | MODE_REC);
f->hdl = sio_open(d->path, mode, 1); d->sio.hdl = sio_open(d->path, mode, 1);
if (f->hdl == NULL) { if (d->sio.hdl == NULL) {
if (mode != (SIO_PLAY | SIO_REC)) if (mode != (SIO_PLAY | SIO_REC))
return 0; return 0;
f->hdl = sio_open(d->path, SIO_PLAY, 1); d->sio.hdl = sio_open(d->path, SIO_PLAY, 1);
if (f->hdl != NULL) if (d->sio.hdl != NULL)
mode = SIO_PLAY; mode = SIO_PLAY;
else { else {
f->hdl = sio_open(d->path, SIO_REC, 1); d->sio.hdl = sio_open(d->path, SIO_REC, 1);
if (f->hdl != NULL) if (d->sio.hdl != NULL)
mode = SIO_REC; mode = SIO_REC;
else else
return 0; return 0;
@ -212,9 +201,9 @@ siofile_open(struct siofile *f, struct dev *d)
par.round = d->round; par.round = d->round;
if (d->rate) if (d->rate)
par.rate = d->rate; par.rate = d->rate;
if (!sio_setpar(f->hdl, &par)) if (!sio_setpar(d->sio.hdl, &par))
goto bad_close; goto bad_close;
if (!sio_getpar(f->hdl, &par)) if (!sio_getpar(d->sio.hdl, &par))
goto bad_close; goto bad_close;
d->par.bits = par.bits; d->par.bits = par.bits;
d->par.bps = par.bps; d->par.bps = par.bps;
@ -225,7 +214,6 @@ siofile_open(struct siofile *f, struct dev *d)
d->pchan = par.pchan; d->pchan = par.pchan;
if (mode & SIO_REC) if (mode & SIO_REC)
d->rchan = par.rchan; d->rchan = par.rchan;
f->dev = d;
d->bufsz = par.bufsz; d->bufsz = par.bufsz;
d->round = par.round; d->round = par.round;
d->rate = par.rate; d->rate = par.rate;
@ -233,106 +221,103 @@ siofile_open(struct siofile *f, struct dev *d)
d->mode &= ~(MODE_PLAY | MODE_MON); d->mode &= ~(MODE_PLAY | MODE_MON);
if (!(mode & MODE_REC)) if (!(mode & MODE_REC))
d->mode &= ~MODE_REC; d->mode &= ~MODE_REC;
sio_onmove(f->hdl, siofile_onmove, f); sio_onmove(d->sio.hdl, dev_sio_onmove, d);
f->file = file_new(&siofile_ops, f, d->path, sio_nfds(f->hdl)); d->sio.file = file_new(&dev_sio_ops, d, d->path, sio_nfds(d->sio.hdl));
return 1; return 1;
bad_close: bad_close:
sio_close(f->hdl); sio_close(d->sio.hdl);
return 0; return 0;
} }
void void
siofile_close(struct siofile *f) dev_sio_close(struct dev *d)
{ {
#ifdef DEBUG #ifdef DEBUG
if (log_level >= 3) { if (log_level >= 3) {
siofile_log(f); dev_log(d);
log_puts(": closed\n"); log_puts(": closed\n");
} }
#endif #endif
file_del(f->file); file_del(d->sio.file);
sio_close(f->hdl); sio_close(d->sio.hdl);
} }
void void
siofile_start(struct siofile *f) dev_sio_start(struct dev *d)
{ {
struct dev *d = f->dev; if (!sio_start(d->sio.hdl)) {
if (!sio_start(f->hdl)) {
if (log_level >= 1) { if (log_level >= 1) {
siofile_log(f); dev_log(d);
log_puts(": failed to start device\n"); log_puts(": failed to start device\n");
} }
return; return;
} }
if (d->mode & MODE_PLAY) { if (d->mode & MODE_PLAY) {
f->cstate = SIOFILE_CYCLE; d->sio.cstate = DEV_SIO_CYCLE;
f->todo = 0; d->sio.todo = 0;
} else { } else {
f->cstate = SIOFILE_READ; d->sio.cstate = DEV_SIO_READ;
f->todo = d->round * d->rchan * d->par.bps; d->sio.todo = d->round * d->rchan * d->par.bps;
} }
#ifdef DEBUG #ifdef DEBUG
f->pused = 0; d->sio.pused = 0;
f->rused = 0; d->sio.rused = 0;
f->sum_utime = 0; d->sio.sum_utime = 0;
f->sum_wtime = 0; d->sio.sum_wtime = 0;
f->wtime = file_wtime; d->sio.wtime = file_wtime;
f->utime = file_utime; d->sio.utime = file_utime;
if (log_level >= 3) { if (log_level >= 3) {
siofile_log(f); dev_log(d);
log_puts(": started\n"); log_puts(": started\n");
} }
#endif #endif
} }
void void
siofile_stop(struct siofile *f) dev_sio_stop(struct dev *d)
{ {
if (!sio_eof(f->hdl) && !sio_stop(f->hdl)) { if (!sio_eof(d->sio.hdl) && !sio_stop(d->sio.hdl)) {
if (log_level >= 1) { if (log_level >= 1) {
siofile_log(f); dev_log(d);
log_puts(": failed to stop device\n"); log_puts(": failed to stop device\n");
} }
return; return;
} }
#ifdef DEBUG #ifdef DEBUG
if (log_level >= 3) { if (log_level >= 3) {
siofile_log(f); dev_log(d);
log_puts(": stopped, load avg = "); log_puts(": stopped, load avg = ");
log_puti(f->sum_utime / 1000); log_puti(d->sio.sum_utime / 1000);
log_puts(" / "); log_puts(" / ");
log_puti(f->sum_wtime / 1000); log_puti(d->sio.sum_wtime / 1000);
log_puts("\n"); log_puts("\n");
} }
#endif #endif
} }
int int
siofile_pollfd(void *arg, struct pollfd *pfd) dev_sio_pollfd(void *arg, struct pollfd *pfd)
{ {
struct siofile *f = arg; struct dev *d = arg;
int events; int events;
events = (f->cstate == SIOFILE_READ) ? POLLIN : POLLOUT; events = (d->sio.cstate == DEV_SIO_READ) ? POLLIN : POLLOUT;
return sio_pollfd(f->hdl, pfd, events); return sio_pollfd(d->sio.hdl, pfd, events);
} }
int int
siofile_revents(void *arg, struct pollfd *pfd) dev_sio_revents(void *arg, struct pollfd *pfd)
{ {
struct siofile *f = arg; struct dev *d = arg;
f->events = sio_revents(f->hdl, pfd); d->sio.events = sio_revents(d->sio.hdl, pfd);
return f->events; return d->sio.events;
} }
void void
siofile_run(void *arg) dev_sio_run(void *arg)
{ {
struct siofile *f = arg; struct dev *d = arg;
struct dev *d = f->dev;
/* /*
* sio_read() and sio_write() would block at the end of the * sio_read() and sio_write() would block at the end of the
@ -343,69 +328,69 @@ siofile_run(void *arg)
for (;;) { for (;;) {
if (d->pstate != DEV_RUN) if (d->pstate != DEV_RUN)
return; return;
switch (f->cstate) { switch (d->sio.cstate) {
case SIOFILE_READ: case DEV_SIO_READ:
#ifdef DEBUG #ifdef DEBUG
if (!(f->events & POLLIN)) { if (!(d->sio.events & POLLIN)) {
siofile_log(f); dev_log(d);
log_puts(": recording, but POLLIN not set\n"); log_puts(": recording, but POLLIN not set\n");
panic(); panic();
} }
#endif #endif
if (!siofile_rec(f)) if (!dev_sio_read(d))
return; return;
#ifdef DEBUG #ifdef DEBUG
f->rused -= d->round; d->sio.rused -= d->round;
if (f->rused >= d->round) { if (d->sio.rused >= d->round) {
siofile_log(f); dev_log(d);
log_puts(": rec hw xrun, rused = "); log_puts(": rec hw xrun, rused = ");
log_puti(f->rused); log_puti(d->sio.rused);
log_puts("/"); log_puts("/");
log_puti(d->bufsz); log_puti(d->bufsz);
log_puts("\n"); log_puts("\n");
} }
if (f->rused < 0 || f->rused >= d->bufsz) { if (d->sio.rused < 0 || d->sio.rused >= d->bufsz) {
/* device driver or libsndio bug */ /* device driver or libsndio bug */
siofile_log(f); dev_log(d);
log_puts(": out of bounds rused = "); log_puts(": out of bounds rused = ");
log_puti(f->rused); log_puti(d->sio.rused);
log_puts("/"); log_puts("/");
log_puti(d->bufsz); log_puti(d->bufsz);
log_puts("\n"); log_puts("\n");
panic(); panic();
} }
#endif #endif
f->cstate = SIOFILE_CYCLE; d->sio.cstate = DEV_SIO_CYCLE;
break; break;
case SIOFILE_CYCLE: case DEV_SIO_CYCLE:
dev_cycle(d); dev_cycle(d);
if (d->mode & MODE_PLAY) { if (d->mode & MODE_PLAY) {
f->cstate = SIOFILE_WRITE; d->sio.cstate = DEV_SIO_WRITE;
f->todo = d->round * d->pchan * d->par.bps; d->sio.todo = d->round * d->pchan * d->par.bps;
break; break;
} else { } else {
f->cstate = SIOFILE_READ; d->sio.cstate = DEV_SIO_READ;
f->todo = d->round * d->rchan * d->par.bps; d->sio.todo = d->round * d->rchan * d->par.bps;
return; return;
} }
case SIOFILE_WRITE: case DEV_SIO_WRITE:
if (!siofile_play(f)) if (!dev_sio_write(d))
return; return;
#ifdef DEBUG #ifdef DEBUG
f->pused += d->round; d->sio.pused += d->round;
if (d->prime == 0 && f->pused <= d->bufsz - d->round) { if (d->prime == 0 && d->sio.pused <= d->bufsz - d->round) {
siofile_log(f); dev_log(d);
log_puts(": play hw xrun, pused = "); log_puts(": play hw xrun, pused = ");
log_puti(f->pused); log_puti(d->sio.pused);
log_puts("/"); log_puts("/");
log_puti(d->bufsz); log_puti(d->bufsz);
log_puts("\n"); log_puts("\n");
} }
if (f->pused < 0 || f->pused > d->bufsz) { if (d->sio.pused < 0 || d->sio.pused > d->bufsz) {
/* device driver or libsndio bug */ /* device driver or libsndio bug */
siofile_log(f); dev_log(d);
log_puts(": out of bounds pused = "); log_puts(": out of bounds pused = ");
log_puti(f->pused); log_puti(d->sio.pused);
log_puts("/"); log_puts("/");
log_puti(d->bufsz); log_puti(d->bufsz);
log_puts("\n"); log_puts("\n");
@ -416,20 +401,19 @@ siofile_run(void *arg)
if (d->poffs == d->bufsz) if (d->poffs == d->bufsz)
d->poffs = 0; d->poffs = 0;
if ((d->mode & MODE_REC) && d->prime == 0) { if ((d->mode & MODE_REC) && d->prime == 0) {
f->cstate = SIOFILE_READ; d->sio.cstate = DEV_SIO_READ;
f->todo = d->round * d->rchan * d->par.bps; d->sio.todo = d->round * d->rchan * d->par.bps;
} else } else
f->cstate = SIOFILE_CYCLE; d->sio.cstate = DEV_SIO_CYCLE;
return; return;
} }
} }
} }
void void
siofile_hup(void *arg) dev_sio_hup(void *arg)
{ {
struct siofile *f = arg; struct dev *d = arg;
struct dev *d = f->dev;
dev_close(d); dev_close(d);
} }

View File

@ -19,7 +19,7 @@
struct dev; struct dev;
struct siofile { struct siofile_ {
struct sio_hdl *hdl; struct sio_hdl *hdl;
unsigned int todo; unsigned int todo;
#ifdef DEBUG #ifdef DEBUG
@ -27,21 +27,17 @@ struct siofile {
long long sum_wtime, sum_utime; long long sum_wtime, sum_utime;
int pused, rused, events; int pused, rused, events;
#endif #endif
struct dev *dev;
struct file *file; struct file *file;
#define SIOFILE_READ 0 #define DEV_SIO_READ 0
#define SIOFILE_CYCLE 1 #define DEV_SIO_CYCLE 1
#define SIOFILE_WRITE 2 #define DEV_SIO_WRITE 2
int cstate; int cstate;
}; };
int siofile_open(struct siofile *, struct dev *); int dev_sio_open(struct dev *);
void siofile_close(struct siofile *); void dev_sio_close(struct dev *);
void siofile_log(struct siofile *); void dev_sio_log(struct dev *);
void siofile_start(struct siofile *); void dev_sio_start(struct dev *);
void siofile_stop(struct siofile *); void dev_sio_stop(struct dev *);
void siofile_read(struct siofile *, unsigned int);
void siofile_write(struct siofile *, unsigned int);
#endif /* !defined(SIOFILE_H) */ #endif /* !defined(SIOFILE_H) */