[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.20

1.20    ! ratchov     1: /*     $OpenBSD: safile.c,v 1.19 2009/11/05 08:36:48 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"
1.20    ! ratchov    33: #ifdef DEBUG
        !            34: #include "dbg.h"
        !            35: #endif
1.1       ratchov    36:
                     37: struct safile {
                     38:        struct file file;
1.2       ratchov    39:        struct sio_hdl *hdl;
1.15      ratchov    40:        int started;
1.1       ratchov    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.18      ratchov    53:        "sio",
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.19      ratchov   149:        if (path == NULL)
                    150:                path = "default";
                    151:        f = (struct safile *)file_new(ops, path, sio_nfds(hdl));
1.11      ratchov   152:        if (f == NULL)
                    153:                goto bad_close;
1.1       ratchov   154:        f->hdl = hdl;
1.15      ratchov   155:        f->started = 0;
1.2       ratchov   156:        sio_onmove(f->hdl, safile_cb, f);
1.1       ratchov   157:        return f;
1.11      ratchov   158:  bad_close:
                    159:        sio_close(hdl);
                    160:        return NULL;
1.1       ratchov   161: }
                    162:
                    163: void
                    164: safile_start(struct file *file)
1.10      ratchov   165: {
1.1       ratchov   166:        struct safile *f = (struct safile *)file;
                    167:
1.2       ratchov   168:        if (!sio_start(f->hdl)) {
1.20    ! ratchov   169: #ifdef DEBUG
        !           170:                dbg_puts(f->file.name);
        !           171:                dbg_puts(": failed to start device\n");
        !           172: #endif
1.9       ratchov   173:                file_close(file);
1.8       ratchov   174:                return;
1.1       ratchov   175:        }
1.15      ratchov   176:        f->started = 1;
1.20    ! ratchov   177: #ifdef DEBUG
        !           178:        if (debug_level >= 3) {
        !           179:                file_dbg(&f->file);
        !           180:                dbg_puts(": started\n");
        !           181:        }
        !           182: #endif
1.1       ratchov   183: }
                    184:
                    185: void
                    186: safile_stop(struct file *file)
                    187: {
                    188:        struct safile *f = (struct safile *)file;
                    189:
1.16      ratchov   190:        f->started = 0;
1.17      ratchov   191:        if (!sio_eof(f->hdl) && !sio_stop(f->hdl)) {
1.20    ! ratchov   192: #ifdef DEBUG
        !           193:                dbg_puts(f->file.name);
        !           194:                dbg_puts(": failed to stop device\n");
        !           195: #endif
1.9       ratchov   196:                file_close(file);
1.8       ratchov   197:                return;
1.1       ratchov   198:        }
1.20    ! ratchov   199: #ifdef DEBUG
        !           200:        if (debug_level >= 3) {
        !           201:                file_dbg(&f->file);
        !           202:                dbg_puts(": stopped\n");
        !           203:        }
        !           204: #endif
1.1       ratchov   205: }
                    206:
                    207: unsigned
                    208: safile_read(struct file *file, unsigned char *data, unsigned count)
                    209: {
                    210:        struct safile *f = (struct safile *)file;
                    211:        unsigned n;
1.18      ratchov   212:
1.2       ratchov   213:        n = sio_read(f->hdl, data, count);
1.1       ratchov   214:        if (n == 0) {
                    215:                f->file.state &= ~FILE_ROK;
1.2       ratchov   216:                if (sio_eof(f->hdl)) {
1.20    ! ratchov   217: #ifdef DEBUG
        !           218:                        dbg_puts(f->file.name);
        !           219:                        dbg_puts(": failed to read from device\n");
        !           220: #endif
1.1       ratchov   221:                        file_eof(&f->file);
                    222:                } else {
1.20    ! ratchov   223: #ifdef DEBUG
        !           224:                        if (debug_level >= 4) {
        !           225:                                file_dbg(&f->file);
        !           226:                                dbg_puts(": reading blocked\n");
        !           227:                        }
        !           228: #endif
1.1       ratchov   229:                }
                    230:                return 0;
                    231:        }
                    232:        return n;
                    233:
                    234: }
                    235:
                    236: unsigned
                    237: safile_write(struct file *file, unsigned char *data, unsigned count)
                    238: {
                    239:        struct safile *f = (struct safile *)file;
                    240:        unsigned n;
1.18      ratchov   241:
1.2       ratchov   242:        n = sio_write(f->hdl, data, count);
1.1       ratchov   243:        if (n == 0) {
                    244:                f->file.state &= ~FILE_WOK;
1.2       ratchov   245:                if (sio_eof(f->hdl)) {
1.20    ! ratchov   246: #ifdef DEBUG
        !           247:                        dbg_puts(f->file.name);
        !           248:                        dbg_puts(": failed to write on device\n");
        !           249: #endif
1.1       ratchov   250:                        file_hup(&f->file);
                    251:                } else {
1.20    ! ratchov   252: #ifdef DEBUG
        !           253:                        if (debug_level >= 4) {
        !           254:                                file_dbg(&f->file);
        !           255:                                dbg_puts(": writing blocked\n");
        !           256:                        }
        !           257: #endif
1.1       ratchov   258:                }
                    259:                return 0;
                    260:        }
                    261:        return n;
                    262: }
                    263:
                    264: int
                    265: safile_nfds(struct file *file)
                    266: {
1.2       ratchov   267:        return sio_nfds(((struct safile *)file)->hdl);
1.1       ratchov   268: }
                    269:
                    270: int
                    271: safile_pollfd(struct file *file, struct pollfd *pfd, int events)
                    272: {
1.2       ratchov   273:        return sio_pollfd(((struct safile *)file)->hdl, pfd, events);
1.1       ratchov   274: }
                    275:
                    276: int
                    277: safile_revents(struct file *file, struct pollfd *pfd)
                    278: {
1.2       ratchov   279:        return sio_revents(((struct safile *)file)->hdl, pfd);
1.1       ratchov   280: }
                    281:
                    282: void
                    283: safile_close(struct file *file)
                    284: {
1.15      ratchov   285:        struct safile *f = (struct safile *)file;
                    286:
                    287:        if (f->started)
                    288:                safile_stop(&f->file);
1.2       ratchov   289:        return sio_close(((struct safile *)file)->hdl);
1.1       ratchov   290: }