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

1.1     ! ratchov     1: /*     $OpenBSD$       */
        !             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:
        !            18: #include <sys/types.h>
        !            19: #include <sys/time.h>
        !            20:
        !            21: #include <poll.h>
        !            22: #include <stdio.h>
        !            23: #include <stdlib.h>
        !            24: #include <string.h>
        !            25: #include <libsa.h>
        !            26:
        !            27: #include "conf.h"
        !            28: #include "file.h"
        !            29: #include "aproc.h"
        !            30: #include "aparams.h"
        !            31: #include "safile.h"
        !            32: #include "dev.h"
        !            33:
        !            34: struct safile {
        !            35:        struct file file;
        !            36:        struct sa_hdl *hdl;
        !            37: #ifdef DEBUG
        !            38:        struct timeval itv, otv;
        !            39: #endif
        !            40: };
        !            41:
        !            42: void safile_close(struct file *);
        !            43: unsigned safile_read(struct file *, unsigned char *, unsigned);
        !            44: unsigned safile_write(struct file *, unsigned char *, unsigned);
        !            45: void safile_start(struct file *);
        !            46: void safile_stop(struct file *);
        !            47: int safile_nfds(struct file *);
        !            48: int safile_pollfd(struct file *, struct pollfd *, int);
        !            49: int safile_revents(struct file *, struct pollfd *);
        !            50:
        !            51: struct fileops safile_ops = {
        !            52:        "libsa",
        !            53:        sizeof(struct safile),
        !            54:        safile_close,
        !            55:        safile_read,
        !            56:        safile_write,
        !            57:        safile_start,
        !            58:        safile_stop,
        !            59:        safile_nfds,
        !            60:        safile_pollfd,
        !            61:        safile_revents
        !            62: };
        !            63:
        !            64: void
        !            65: safile_cb(void *addr, int delta)
        !            66: {
        !            67:        struct safile *f = (struct safile *)addr;
        !            68:        struct aproc *p;
        !            69:
        !            70:        if (delta != 0) {
        !            71:                p = f->file.wproc;
        !            72:                if (p && p->ops->opos)
        !            73:                        p->ops->opos(p, NULL, delta);
        !            74:        }
        !            75:        if (delta != 0) {
        !            76:                p = f->file.rproc;
        !            77:                if (p && p->ops->ipos)
        !            78:                        p->ops->ipos(p, NULL, delta);
        !            79:        }
        !            80: }
        !            81:
        !            82: /*
        !            83:  * open the device
        !            84:  */
        !            85: struct safile *
        !            86: safile_new(struct fileops *ops, char *path,
        !            87:     struct aparams *ipar, struct aparams *opar,
        !            88:     unsigned *bufsz, unsigned *round)
        !            89: {
        !            90:        struct sa_par par;
        !            91:        struct sa_hdl *hdl;
        !            92:        struct safile *f;
        !            93:        int mode;
        !            94:
        !            95:        mode = 0;
        !            96:        if (ipar)
        !            97:                mode |= SA_REC;
        !            98:        if (opar)
        !            99:                mode |= SA_PLAY;
        !           100:        if (!mode)
        !           101:                fprintf(stderr, "%s: must at least play or record", path);
        !           102:        hdl = sa_open(path, mode, 1);
        !           103:        if (hdl == NULL) {
        !           104:                fprintf(stderr, "safile_new: can't open device\n");
        !           105:                return NULL;
        !           106:        }
        !           107:        sa_initpar(&par);
        !           108:        if (ipar) {
        !           109:                par.bits = ipar->bits;
        !           110:                par.bps = ipar->bps;
        !           111:                par.sig = ipar->sig;
        !           112:                par.le = ipar->le;
        !           113:                par.msb = ipar->msb;
        !           114:                par.rate = ipar->rate;
        !           115:                par.rchan = ipar->cmax - ipar->cmin + 1;
        !           116:        } else {
        !           117:                par.bits = opar->bits;
        !           118:                par.bps = opar->bps;
        !           119:                par.sig = opar->sig;
        !           120:                par.le = opar->le;
        !           121:                par.msb = opar->msb;
        !           122:                par.rate = opar->rate;
        !           123:        }
        !           124:        if (opar)
        !           125:                par.pchan = opar->cmax - opar->cmin + 1;
        !           126:        if (*bufsz)
        !           127:                par.bufsz = *bufsz;
        !           128:        if (!sa_setpar(hdl, &par)) {
        !           129:                fprintf(stderr, "safile_new: sa_setpar failed\n");
        !           130:                exit(1);
        !           131:        }
        !           132:        if (!sa_getpar(hdl, &par)) {
        !           133:                fprintf(stderr, "safile_new: sa_getpar failed\n");
        !           134:                exit(1);
        !           135:        }
        !           136:        if (ipar) {
        !           137:                ipar->bits = par.bits;
        !           138:                ipar->bps = par.bps;
        !           139:                ipar->sig = par.sig;
        !           140:                ipar->le = par.le;
        !           141:                ipar->msb = par.msb;
        !           142:                ipar->rate = par.rate;
        !           143:                ipar->cmax = par.rchan - 1;
        !           144:                ipar->cmin = 0;
        !           145:        }
        !           146:        if (opar) {
        !           147:                opar->bits = par.bits;
        !           148:                opar->bps = par.bps;
        !           149:                opar->sig = par.sig;
        !           150:                opar->le = par.le;
        !           151:                opar->msb = par.msb;
        !           152:                opar->rate = par.rate;
        !           153:                opar->cmax = par.pchan - 1;
        !           154:                opar->cmin = 0;
        !           155:        }
        !           156:        *bufsz = par.bufsz;
        !           157:        *round = par.round;
        !           158:        DPRINTF("safile_open: using %u(%u) fpb\n", *bufsz, *round);
        !           159:        f = (struct safile *)file_new(ops, "hdl", sa_nfds(hdl));
        !           160:        f->hdl = hdl;
        !           161:        sa_onmove(f->hdl, safile_cb, f);
        !           162:        return f;
        !           163: }
        !           164:
        !           165: void
        !           166: safile_start(struct file *file)
        !           167: {
        !           168:        struct safile *f = (struct safile *)file;
        !           169:
        !           170:        if (!sa_start(f->hdl)) {
        !           171:                fprintf(stderr, "safile_start: sa_start() failed\n");
        !           172:                exit(1);
        !           173:        }
        !           174:        DPRINTF("safile_start: play/rec started\n");
        !           175: }
        !           176:
        !           177: void
        !           178: safile_stop(struct file *file)
        !           179: {
        !           180:        struct safile *f = (struct safile *)file;
        !           181:
        !           182:        if (!sa_stop(f->hdl)) {
        !           183:                fprintf(stderr, "safile_stop: sa_start() filed\n");
        !           184:                exit(1);
        !           185:        }
        !           186:        DPRINTF("safile_stop: play/rec stopped\n");
        !           187: }
        !           188:
        !           189: unsigned
        !           190: safile_read(struct file *file, unsigned char *data, unsigned count)
        !           191: {
        !           192:        struct safile *f = (struct safile *)file;
        !           193:        unsigned n;
        !           194: #ifdef DEBUG
        !           195:        struct timeval tv0, tv1, dtv;
        !           196:        unsigned us;
        !           197:
        !           198:        if (!(f->file.state & FILE_ROK)) {
        !           199:                DPRINTF("file_read: %s: bad state\n", f->file.name);
        !           200:                abort();
        !           201:        }
        !           202:        gettimeofday(&tv0, NULL);
        !           203: #endif
        !           204:        n = sa_read(f->hdl, data, count);
        !           205:        if (n == 0) {
        !           206:                f->file.state &= ~FILE_ROK;
        !           207:                if (sa_eof(f->hdl)) {
        !           208:                        fprintf(stderr, "safile_read: eof\n");
        !           209:                        file_eof(&f->file);
        !           210:                } else {
        !           211:                        DPRINTFN(3, "safile_read: %s: blocking...\n",
        !           212:                            f->file.name);
        !           213:                }
        !           214:                return 0;
        !           215:        }
        !           216: #ifdef DEBUG
        !           217:        gettimeofday(&tv1, NULL);
        !           218:        timersub(&tv1, &tv0, &dtv);
        !           219:        us = dtv.tv_sec * 1000000 + dtv.tv_usec;
        !           220:        DPRINTFN(us < 5000 ? 4 : 1,
        !           221:            "safile_read: %s: got %d bytes in %uus\n",
        !           222:            f->file.name, n, us);
        !           223: #endif
        !           224:        return n;
        !           225:
        !           226: }
        !           227:
        !           228: unsigned
        !           229: safile_write(struct file *file, unsigned char *data, unsigned count)
        !           230: {
        !           231:        struct safile *f = (struct safile *)file;
        !           232:        unsigned n;
        !           233: #ifdef DEBUG
        !           234:        struct timeval tv0, tv1, dtv;
        !           235:        unsigned us;
        !           236:
        !           237:        if (!(f->file.state & FILE_WOK)) {
        !           238:                DPRINTF("safile_write: %s: bad state\n", f->file.name);
        !           239:                abort();
        !           240:        }
        !           241:        gettimeofday(&tv0, NULL);
        !           242: #endif
        !           243:        n = sa_write(f->hdl, data, count);
        !           244:        if (n == 0) {
        !           245:                f->file.state &= ~FILE_WOK;
        !           246:                if (sa_eof(f->hdl)) {
        !           247:                        fprintf(stderr, "safile_write: %s: hup\n", f->file.name);
        !           248:                        file_hup(&f->file);
        !           249:                } else {
        !           250:                        DPRINTFN(3, "safile_write: %s: blocking...\n",
        !           251:                            f->file.name);
        !           252:                }
        !           253:                return 0;
        !           254:        }
        !           255: #ifdef DEBUG
        !           256:        gettimeofday(&tv1, NULL);
        !           257:        timersub(&tv1, &tv0, &dtv);
        !           258:        us = dtv.tv_sec * 1000000 + dtv.tv_usec;
        !           259:        DPRINTFN(us < 5000 ? 4 : 1,
        !           260:            "safile_write: %s: wrote %d bytes in %uus\n",
        !           261:            f->file.name, n, us);
        !           262: #endif
        !           263:        return n;
        !           264: }
        !           265:
        !           266: int
        !           267: safile_nfds(struct file *file)
        !           268: {
        !           269:        return sa_nfds(((struct safile *)file)->hdl);
        !           270: }
        !           271:
        !           272: int
        !           273: safile_pollfd(struct file *file, struct pollfd *pfd, int events)
        !           274: {
        !           275:        return sa_pollfd(((struct safile *)file)->hdl, pfd, events);
        !           276: }
        !           277:
        !           278: int
        !           279: safile_revents(struct file *file, struct pollfd *pfd)
        !           280: {
        !           281:        return sa_revents(((struct safile *)file)->hdl, pfd);
        !           282: }
        !           283:
        !           284: void
        !           285: safile_close(struct file *file)
        !           286: {
        !           287:        return sa_close(((struct safile *)file)->hdl);
        !           288: }