[BACK]Return to safile.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / aucat

Annotation of src/usr.bin/aucat/safile.c, Revision 1.16

1.16    ! ratchov     1: /*     $OpenBSD: safile.c,v 1.15 2009/08/28 06:30:17 ratchov Exp $     */
1.1       ratchov     2: /*
                      3:  * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
                      4:  *
                      5:  * Permission to use, copy, modify, and distribute this software for any
                      6:  * purpose with or without fee is hereby granted, provided that the above
                      7:  * copyright notice and this permission notice appear in all copies.
                      8:  *
                      9:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     11:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     15:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     16:  */
                     17:
1.14      ratchov    18: #include <sys/time.h>
1.1       ratchov    19: #include <sys/types.h>
                     20:
                     21: #include <poll.h>
1.14      ratchov    22: #include <sndio.h>
1.1       ratchov    23: #include <stdio.h>
                     24: #include <stdlib.h>
                     25: #include <string.h>
                     26:
1.14      ratchov    27: #include "aparams.h"
                     28: #include "aproc.h"
1.1       ratchov    29: #include "conf.h"
1.14      ratchov    30: #include "dev.h"
1.1       ratchov    31: #include "file.h"
                     32: #include "safile.h"
                     33:
                     34: struct safile {
                     35:        struct file file;
1.2       ratchov    36:        struct sio_hdl *hdl;
1.15      ratchov    37:        int started;
1.10      ratchov    38: #ifdef DEBUG
1.1       ratchov    39:        struct timeval itv, otv;
                     40: #endif
                     41: };
                     42:
                     43: void safile_close(struct file *);
                     44: unsigned safile_read(struct file *, unsigned char *, unsigned);
                     45: unsigned safile_write(struct file *, unsigned char *, unsigned);
                     46: void safile_start(struct file *);
                     47: void safile_stop(struct file *);
                     48: int safile_nfds(struct file *);
                     49: int safile_pollfd(struct file *, struct pollfd *, int);
                     50: int safile_revents(struct file *, struct pollfd *);
                     51:
                     52: struct fileops safile_ops = {
1.3       ratchov    53:        "sndio",
1.1       ratchov    54:        sizeof(struct safile),
                     55:        safile_close,
                     56:        safile_read,
                     57:        safile_write,
                     58:        safile_start,
                     59:        safile_stop,
                     60:        safile_nfds,
                     61:        safile_pollfd,
                     62:        safile_revents
                     63: };
                     64:
                     65: void
                     66: safile_cb(void *addr, int delta)
                     67: {
                     68:        struct safile *f = (struct safile *)addr;
                     69:        struct aproc *p;
                     70:
                     71:        if (delta != 0) {
                     72:                p = f->file.wproc;
                     73:                if (p && p->ops->opos)
                     74:                        p->ops->opos(p, NULL, delta);
                     75:        }
                     76:        if (delta != 0) {
                     77:                p = f->file.rproc;
                     78:                if (p && p->ops->ipos)
                     79:                        p->ops->ipos(p, NULL, delta);
                     80:        }
                     81: }
                     82:
                     83: /*
1.14      ratchov    84:  * Open the device.
1.1       ratchov    85:  */
                     86: struct safile *
                     87: safile_new(struct fileops *ops, char *path,
                     88:     struct aparams *ipar, struct aparams *opar,
1.5       ratchov    89:     unsigned *bufsz, unsigned *round)
1.1       ratchov    90: {
1.2       ratchov    91:        struct sio_par par;
                     92:        struct sio_hdl *hdl;
1.1       ratchov    93:        struct safile *f;
                     94:        int mode;
                     95:
                     96:        mode = 0;
                     97:        if (ipar)
1.2       ratchov    98:                mode |= SIO_REC;
1.1       ratchov    99:        if (opar)
1.2       ratchov   100:                mode |= SIO_PLAY;
                    101:        hdl = sio_open(path, mode, 1);
1.12      ratchov   102:        if (hdl == NULL)
1.1       ratchov   103:                return NULL;
1.2       ratchov   104:        sio_initpar(&par);
1.1       ratchov   105:        if (ipar) {
                    106:                par.bits = ipar->bits;
                    107:                par.bps = ipar->bps;
                    108:                par.sig = ipar->sig;
                    109:                par.le = ipar->le;
                    110:                par.msb = ipar->msb;
                    111:                par.rate = ipar->rate;
                    112:                par.rchan = ipar->cmax - ipar->cmin + 1;
                    113:        } else {
                    114:                par.bits = opar->bits;
                    115:                par.bps = opar->bps;
                    116:                par.sig = opar->sig;
                    117:                par.le = opar->le;
                    118:                par.msb = opar->msb;
                    119:                par.rate = opar->rate;
                    120:        }
                    121:        if (opar)
                    122:                par.pchan = opar->cmax - opar->cmin + 1;
1.6       ratchov   123:        par.appbufsz = *bufsz;
1.3       ratchov   124:        par.round = *round;
1.5       ratchov   125:        if (!sio_setpar(hdl, &par))
1.11      ratchov   126:                goto bad_close;
1.5       ratchov   127:        if (!sio_getpar(hdl, &par))
1.11      ratchov   128:                goto bad_close;
1.1       ratchov   129:        if (ipar) {
                    130:                ipar->bits = par.bits;
                    131:                ipar->bps = par.bps;
                    132:                ipar->sig = par.sig;
                    133:                ipar->le = par.le;
                    134:                ipar->msb = par.msb;
                    135:                ipar->rate = par.rate;
1.7       ratchov   136:                ipar->cmax = ipar->cmin + par.rchan - 1;
1.1       ratchov   137:        }
                    138:        if (opar) {
                    139:                opar->bits = par.bits;
                    140:                opar->bps = par.bps;
                    141:                opar->sig = par.sig;
                    142:                opar->le = par.le;
                    143:                opar->msb = par.msb;
                    144:                opar->rate = par.rate;
1.7       ratchov   145:                opar->cmax = opar->cmin + par.pchan - 1;
1.1       ratchov   146:        }
                    147:        *bufsz = par.bufsz;
                    148:        *round = par.round;
1.3       ratchov   149:        DPRINTF("safile_new: using %u(%u) fpb\n", *bufsz, *round);
1.2       ratchov   150:        f = (struct safile *)file_new(ops, "hdl", sio_nfds(hdl));
1.11      ratchov   151:        if (f == NULL)
                    152:                goto bad_close;
1.1       ratchov   153:        f->hdl = hdl;
1.15      ratchov   154:        f->started = 0;
1.2       ratchov   155:        sio_onmove(f->hdl, safile_cb, f);
1.1       ratchov   156:        return f;
1.11      ratchov   157:  bad_close:
                    158:        sio_close(hdl);
                    159:        return NULL;
1.1       ratchov   160: }
                    161:
                    162: void
                    163: safile_start(struct file *file)
1.10      ratchov   164: {
1.1       ratchov   165:        struct safile *f = (struct safile *)file;
                    166:
1.2       ratchov   167:        if (!sio_start(f->hdl)) {
1.8       ratchov   168:                DPRINTF("safile_start: sio_start() failed\n");
1.9       ratchov   169:                file_close(file);
1.8       ratchov   170:                return;
1.1       ratchov   171:        }
1.15      ratchov   172:        f->started = 1;
1.1       ratchov   173:        DPRINTF("safile_start: play/rec started\n");
                    174: }
                    175:
                    176: void
                    177: safile_stop(struct file *file)
                    178: {
                    179:        struct safile *f = (struct safile *)file;
                    180:
1.16    ! ratchov   181:        f->started = 0;
1.2       ratchov   182:        if (!sio_stop(f->hdl)) {
1.8       ratchov   183:                DPRINTF("safile_stop: sio_stop() filed\n");
1.9       ratchov   184:                file_close(file);
1.8       ratchov   185:                return;
1.1       ratchov   186:        }
                    187:        DPRINTF("safile_stop: play/rec stopped\n");
                    188: }
                    189:
                    190: unsigned
                    191: safile_read(struct file *file, unsigned char *data, unsigned count)
                    192: {
                    193:        struct safile *f = (struct safile *)file;
                    194:        unsigned n;
                    195: #ifdef DEBUG
                    196:        struct timeval tv0, tv1, dtv;
                    197:        unsigned us;
                    198:
                    199:        if (!(f->file.state & FILE_ROK)) {
1.14      ratchov   200:                DPRINTF("safile_read: %s: bad state\n", f->file.name);
1.1       ratchov   201:                abort();
                    202:        }
                    203:        gettimeofday(&tv0, NULL);
                    204: #endif
1.2       ratchov   205:        n = sio_read(f->hdl, data, count);
1.1       ratchov   206:        if (n == 0) {
                    207:                f->file.state &= ~FILE_ROK;
1.2       ratchov   208:                if (sio_eof(f->hdl)) {
1.1       ratchov   209:                        fprintf(stderr, "safile_read: eof\n");
                    210:                        file_eof(&f->file);
                    211:                } else {
                    212:                        DPRINTFN(3, "safile_read: %s: blocking...\n",
                    213:                            f->file.name);
                    214:                }
                    215:                return 0;
                    216:        }
                    217: #ifdef DEBUG
                    218:        gettimeofday(&tv1, NULL);
                    219:        timersub(&tv1, &tv0, &dtv);
1.10      ratchov   220:        us = dtv.tv_sec * 1000000 + dtv.tv_usec;
1.13      ratchov   221:        DPRINTFN(us < 5000 ? 4 : 2,
1.10      ratchov   222:            "safile_read: %s: got %d bytes in %uus\n",
1.1       ratchov   223:            f->file.name, n, us);
                    224: #endif
                    225:        return n;
                    226:
                    227: }
                    228:
                    229: unsigned
                    230: safile_write(struct file *file, unsigned char *data, unsigned count)
                    231: {
                    232:        struct safile *f = (struct safile *)file;
                    233:        unsigned n;
                    234: #ifdef DEBUG
                    235:        struct timeval tv0, tv1, dtv;
                    236:        unsigned us;
1.10      ratchov   237:
1.1       ratchov   238:        if (!(f->file.state & FILE_WOK)) {
                    239:                DPRINTF("safile_write: %s: bad state\n", f->file.name);
                    240:                abort();
                    241:        }
                    242:        gettimeofday(&tv0, NULL);
                    243: #endif
1.2       ratchov   244:        n = sio_write(f->hdl, data, count);
1.1       ratchov   245:        if (n == 0) {
                    246:                f->file.state &= ~FILE_WOK;
1.2       ratchov   247:                if (sio_eof(f->hdl)) {
1.1       ratchov   248:                        fprintf(stderr, "safile_write: %s: hup\n", f->file.name);
                    249:                        file_hup(&f->file);
                    250:                } else {
                    251:                        DPRINTFN(3, "safile_write: %s: blocking...\n",
                    252:                            f->file.name);
                    253:                }
                    254:                return 0;
                    255:        }
                    256: #ifdef DEBUG
                    257:        gettimeofday(&tv1, NULL);
                    258:        timersub(&tv1, &tv0, &dtv);
1.10      ratchov   259:        us = dtv.tv_sec * 1000000 + dtv.tv_usec;
1.13      ratchov   260:        DPRINTFN(us < 5000 ? 4 : 2,
1.1       ratchov   261:            "safile_write: %s: wrote %d bytes in %uus\n",
                    262:            f->file.name, n, us);
                    263: #endif
                    264:        return n;
                    265: }
                    266:
                    267: int
                    268: safile_nfds(struct file *file)
                    269: {
1.2       ratchov   270:        return sio_nfds(((struct safile *)file)->hdl);
1.1       ratchov   271: }
                    272:
                    273: int
                    274: safile_pollfd(struct file *file, struct pollfd *pfd, int events)
                    275: {
1.2       ratchov   276:        return sio_pollfd(((struct safile *)file)->hdl, pfd, events);
1.1       ratchov   277: }
                    278:
                    279: int
                    280: safile_revents(struct file *file, struct pollfd *pfd)
                    281: {
1.2       ratchov   282:        return sio_revents(((struct safile *)file)->hdl, pfd);
1.1       ratchov   283: }
                    284:
                    285: void
                    286: safile_close(struct file *file)
                    287: {
1.15      ratchov   288:        struct safile *f = (struct safile *)file;
                    289:
                    290:        if (f->started)
                    291:                safile_stop(&f->file);
1.2       ratchov   292:        return sio_close(((struct safile *)file)->hdl);
1.1       ratchov   293: }