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

Annotation of src/usr.bin/aucat/dev.c, Revision 1.14

1.14    ! ratchov     1: /*     $OpenBSD: dev.c,v 1.13 2008/11/09 16:26:07 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: #include <stdio.h>
                     18: #include <stdlib.h>
                     19: #include <unistd.h>
                     20:
                     21: #include "dev.h"
                     22: #include "abuf.h"
                     23: #include "aproc.h"
1.3       ratchov    24: #include "pipe.h"
1.1       ratchov    25: #include "conf.h"
1.3       ratchov    26: #include "safile.h"
1.1       ratchov    27:
1.3       ratchov    28: unsigned dev_bufsz, dev_round, dev_rate;
                     29: unsigned dev_rate_div, dev_round_div;
1.1       ratchov    30: struct aparams dev_ipar, dev_opar;
                     31: struct aproc *dev_mix, *dev_sub, *dev_rec, *dev_play;
1.3       ratchov    32: struct file *dev_file;
1.1       ratchov    33:
                     34: /*
1.3       ratchov    35:  * supported rates
1.1       ratchov    36:  */
1.3       ratchov    37: #define NRATES (sizeof(dev_rates) / sizeof(dev_rates[0]))
                     38: unsigned dev_rates[] = {
                     39:          6400,   7200,   8000,   9600,  11025,  12000,
                     40:         12800,  14400,  16000,  19200,  22050,  24000,
                     41:         25600,  28800,  32000,  38400,  44100,  48000,
                     42:         51200,  57600,  64000,  76800,  88200,  96000,
                     43:        102400, 115200, 128000, 153600, 176400, 192000
                     44: };
1.1       ratchov    45:
                     46: /*
1.3       ratchov    47:  * factors of supported rates
1.1       ratchov    48:  */
1.3       ratchov    49: #define NPRIMES (sizeof(dev_primes) / sizeof(dev_primes[0]))
                     50: unsigned dev_primes[] = {2, 3, 5, 7};
1.1       ratchov    51:
1.3       ratchov    52: int
                     53: dev_setrate(unsigned rate)
1.1       ratchov    54: {
1.3       ratchov    55:        unsigned i, r, p;
1.1       ratchov    56:
1.3       ratchov    57:        r = 1000 * rate;
                     58:        for (i = 0; i < NRATES; i++) {
                     59:                if (i == NRATES) {
                     60:                        fprintf(stderr, "dev_setrate: %u, unsupported\n", rate);
                     61:                        return 0;
                     62:                }
                     63:                if (r > 996 * dev_rates[i] &&
                     64:                    r < 1004 * dev_rates[i]) {
                     65:                        dev_rate = dev_rates[i];
1.1       ratchov    66:                        break;
                     67:                }
1.3       ratchov    68:        }
                     69:
                     70:        dev_rate_div = dev_rate;
                     71:        dev_round_div = dev_round;
                     72:        for (i = 0; i < NPRIMES; i++) {
                     73:                p = dev_primes[i];
                     74:                while (dev_rate_div % p == 0 && dev_round_div % p == 0) {
                     75:                        dev_rate_div /= p;
                     76:                        dev_round_div /= p;
1.1       ratchov    77:                }
                     78:        }
1.3       ratchov    79:        return 1;
1.1       ratchov    80: }
                     81:
                     82: void
1.3       ratchov    83: dev_roundrate(unsigned *newrate, unsigned *newround)
1.1       ratchov    84: {
1.3       ratchov    85:        *newrate += dev_rate_div - 1;
                     86:        *newrate -= *newrate % dev_rate_div;
                     87:        *newround = *newrate * dev_round_div / dev_rate_div;
1.1       ratchov    88: }
                     89:
                     90: /*
                     91:  * open the device with the given hardware parameters and create a mixer
                     92:  * and a multiplexer connected to it with all necessary conversions
                     93:  * setup
                     94:  */
                     95: void
1.3       ratchov    96: dev_init(char *devpath,
1.11      ratchov    97:     struct aparams *dipar, struct aparams *dopar,
                     98:     unsigned bufsz, int blkio)
1.1       ratchov    99: {
                    100:        struct aparams ipar, opar;
                    101:        struct aproc *conv;
                    102:        struct abuf *buf;
1.3       ratchov   103:        unsigned nfr, ibufsz, obufsz;
1.1       ratchov   104:
1.3       ratchov   105:        /*
1.11      ratchov   106:         * ask for 1/4 of the buffer for the kernel ring and
                    107:         * limit the block size to 1/4 of the requested buffer
1.3       ratchov   108:         */
                    109:        dev_bufsz = (bufsz + 3) / 4;
1.11      ratchov   110:        dev_round = (bufsz + 3) / 4;
1.3       ratchov   111:        dev_file = (struct file *)safile_new(&safile_ops, devpath,
1.11      ratchov   112:            dipar, dopar, &dev_bufsz, &dev_round, blkio);
1.3       ratchov   113:        if (!dev_file)
                    114:                exit(1);
                    115:        if (!dev_setrate(dipar ? dipar->rate : dopar->rate))
1.1       ratchov   116:                exit(1);
1.3       ratchov   117:        if (dipar) {
                    118:                dipar->rate = dev_rate;
                    119:                if (debug_level > 0) {
1.9       ratchov   120:                        fprintf(stderr, "dev_init: hw recording ");
1.3       ratchov   121:                        aparams_print(dipar);
1.9       ratchov   122:                        fprintf(stderr, "\n");
1.3       ratchov   123:                }
                    124:        }
                    125:        if (dopar) {
                    126:                dopar->rate = dev_rate;
                    127:                if (debug_level > 0) {
1.9       ratchov   128:                        fprintf(stderr, "dev_init: hw playing ");
1.3       ratchov   129:                        aparams_print(dopar);
1.9       ratchov   130:                        fprintf(stderr, "\n");
1.3       ratchov   131:                }
                    132:        }
1.11      ratchov   133:        ibufsz = obufsz = dev_bufsz;
                    134:        bufsz = (bufsz > dev_bufsz) ? bufsz - dev_bufsz : 0;
1.1       ratchov   135:
                    136:        /*
1.11      ratchov   137:         * use 1/8 of the buffer for the mixer/converters.  Since we
                    138:         * already consumed 1/4 for the device, bufsz represents the
                    139:         * remaining 3/4. So 1/8 is 1/6 of 3/4
                    140:         */
                    141:        nfr = (bufsz + 5) / 6;
                    142:        nfr += dev_round - 1;
                    143:        nfr -= nfr % dev_round;
                    144:        if (nfr == 0)
                    145:                nfr = dev_round;
                    146:
                    147:        /*
                    148:         * create record chain
1.1       ratchov   149:         */
                    150:        if (dipar) {
                    151:                aparams_init(&ipar, dipar->cmin, dipar->cmax, dipar->rate);
                    152:                /*
                    153:                 * create the read end
                    154:                 */
                    155:                dev_rec = rpipe_new(dev_file);
1.4       ratchov   156:                buf = abuf_new(nfr, dipar);
1.1       ratchov   157:                aproc_setout(dev_rec, buf);
1.3       ratchov   158:                ibufsz += nfr;
1.1       ratchov   159:
                    160:                /*
                    161:                 * append a converter, if needed
                    162:                 */
1.4       ratchov   163:                if (!aparams_eqenc(dipar, &ipar)) {
1.9       ratchov   164:                        conv = dec_new("subin", dipar);
1.1       ratchov   165:                        aproc_setin(conv, buf);
1.4       ratchov   166:                        buf = abuf_new(nfr, &ipar);
1.1       ratchov   167:                        aproc_setout(conv, buf);
1.3       ratchov   168:                        ibufsz += nfr;
1.1       ratchov   169:                }
                    170:                dev_ipar = ipar;
                    171:
                    172:                /*
                    173:                 * append a "sub" to which clients will connect
                    174:                 */
1.3       ratchov   175:                dev_sub = sub_new("sub", nfr);
1.1       ratchov   176:                aproc_setin(dev_sub, buf);
                    177:        } else {
                    178:                dev_rec = NULL;
                    179:                dev_sub = NULL;
                    180:        }
                    181:
                    182:        /*
                    183:         * create play chain
                    184:         */
                    185:        if (dopar) {
                    186:                aparams_init(&opar, dopar->cmin, dopar->cmax, dopar->rate);
                    187:                /*
                    188:                 * create the write end
                    189:                 */
                    190:                dev_play = wpipe_new(dev_file);
1.4       ratchov   191:                buf = abuf_new(nfr, dopar);
1.1       ratchov   192:                aproc_setin(dev_play, buf);
1.3       ratchov   193:                obufsz += nfr;
                    194:
1.1       ratchov   195:                /*
                    196:                 * append a converter, if needed
                    197:                 */
1.4       ratchov   198:                if (!aparams_eqenc(&opar, dopar)) {
1.9       ratchov   199:                        conv = enc_new("mixout", dopar);
1.1       ratchov   200:                        aproc_setout(conv, buf);
1.4       ratchov   201:                        buf = abuf_new(nfr, &opar);
1.1       ratchov   202:                        aproc_setin(conv, buf);
1.3       ratchov   203:                        obufsz += nfr;
1.1       ratchov   204:                }
                    205:                dev_opar = opar;
                    206:
                    207:                /*
                    208:                 * append a "mix" to which clients will connect
                    209:                 */
1.3       ratchov   210:                dev_mix = mix_new("mix", nfr);
1.1       ratchov   211:                aproc_setout(dev_mix, buf);
                    212:        } else {
                    213:                dev_play = NULL;
                    214:                dev_mix = NULL;
                    215:        }
1.3       ratchov   216:        dev_bufsz = (dopar) ? obufsz : ibufsz;
                    217:        DPRINTF("dev_init: using %u fpb\n", dev_bufsz);
                    218:        dev_start();
1.1       ratchov   219: }
                    220:
                    221: /*
                    222:  * cleanly stop and drain everything and close the device
                    223:  * once both play chain and record chain are gone
                    224:  */
                    225: void
                    226: dev_done(void)
                    227: {
                    228:        struct file *f;
                    229:
1.3       ratchov   230:        if (dev_mix) {
                    231:                /*
                    232:                 * generate EOF on all inputs (but not the device), and
                    233:                 * put the mixer in ``autoquit'' state, so once buffers
                    234:                 * are drained the mixer will terminate and shutdown the
                    235:                 * write-end of the device
                    236:                 *
                    237:                 * NOTE: since file_eof() can destroy the file and
                    238:                 * reorder the file_list, we have to restart the loop
                    239:                 * after each call to file_eof()
                    240:                 */
                    241:        restart:
                    242:                LIST_FOREACH(f, &file_list, entry) {
                    243:                        if (f != dev_file && f->rproc) {
                    244:                                file_eof(f);
                    245:                                goto restart;
                    246:                        }
                    247:                }
                    248:                if (dev_mix)
                    249:                        dev_mix->u.mix.flags |= MIX_AUTOQUIT;
                    250:
                    251:                /*
                    252:                 * wait play chain to terminate
                    253:                 */
                    254:                while (dev_file->wproc != NULL) {
                    255:                        if (!file_poll())
                    256:                                break;
                    257:                }
                    258:                dev_mix = 0;
1.1       ratchov   259:        }
1.3       ratchov   260:        if (dev_sub) {
                    261:                /*
                    262:                 * same as above, but for the record chain: generate eof
                    263:                 * on the read-end of the device and wait record buffers
                    264:                 * to desappear.  We must stop the device first, because
                    265:                 * play-end will underrun (and xrun correction code will
                    266:                 * insert silence on the record-end of the device)
                    267:                 */
                    268:                dev_stop();
                    269:                file_eof(dev_file);
                    270:                if (dev_sub)
                    271:                        dev_sub->u.sub.flags |= SUB_AUTOQUIT;
                    272:                for (;;) {
                    273:                        if (!file_poll())
                    274:                                break;
                    275:                }
                    276:                dev_sub = NULL;
1.1       ratchov   277:        }
                    278: }
                    279:
                    280: /*
                    281:  * start the (paused) device. By default it's paused
                    282:  */
                    283: void
                    284: dev_start(void)
                    285: {
                    286:        if (dev_mix)
                    287:                dev_mix->u.mix.flags |= MIX_DROP;
                    288:        if (dev_sub)
                    289:                dev_sub->u.sub.flags |= SUB_DROP;
1.3       ratchov   290:        dev_file->ops->start(dev_file);
1.1       ratchov   291: }
                    292:
                    293: /*
                    294:  * pause the device
                    295:  */
                    296: void
                    297: dev_stop(void)
                    298: {
1.3       ratchov   299:        dev_file->ops->stop(dev_file);
1.1       ratchov   300:        if (dev_mix)
                    301:                dev_mix->u.mix.flags &= ~MIX_DROP;
                    302:        if (dev_sub)
                    303:                dev_sub->u.sub.flags &= ~SUB_DROP;
                    304: }
                    305:
                    306: /*
1.14    ! ratchov   307:  * find the end points connected to the mix/sub
        !           308:  */
        !           309: int
        !           310: dev_getep(struct abuf **sibuf, struct abuf **sobuf)
        !           311: {
        !           312:        struct abuf *ibuf, *obuf;
        !           313:
        !           314:        if (sibuf) {
        !           315:                ibuf = *sibuf;
        !           316:                for (;;) {
        !           317:                        if (!ibuf || !ibuf->rproc) {
        !           318:                                DPRINTF("dev_getep: reader desappeared\n");
        !           319:                                return 0;
        !           320:                        }
        !           321:                        if (ibuf->rproc == dev_mix)
        !           322:                                break;
        !           323:                        ibuf = LIST_FIRST(&ibuf->rproc->obuflist);
        !           324:                }
        !           325:        }
        !           326:        if (sobuf) {
        !           327:                obuf = *sobuf;
        !           328:                for (;;) {
        !           329:                        if (!obuf || !obuf->wproc) {
        !           330:                                DPRINTF("dev_getep: writer desappeared\n");
        !           331:                                return 0;
        !           332:                        }
        !           333:                        if (obuf->wproc == dev_sub)
        !           334:                                break;
        !           335:                        obuf = LIST_FIRST(&obuf->wproc->ibuflist);
        !           336:                }
        !           337:        }
        !           338:        return 1;
        !           339: }
        !           340:
        !           341: /*
1.3       ratchov   342:  * sync play buffer to rec buffer (for instance when one of
                    343:  * them underruns/overruns)
1.1       ratchov   344:  */
                    345: void
1.3       ratchov   346: dev_sync(struct abuf *ibuf, struct abuf *obuf)
1.1       ratchov   347: {
1.3       ratchov   348:        struct abuf *pbuf, *rbuf;
                    349:        int delta;
                    350:
                    351:        if (!dev_mix || !dev_sub)
                    352:                return;
                    353:        pbuf = LIST_FIRST(&dev_mix->obuflist);
                    354:        if (!pbuf)
                    355:                return;
                    356:        rbuf = LIST_FIRST(&dev_sub->ibuflist);
                    357:        if (!rbuf)
                    358:                return;
1.14    ! ratchov   359:        if (!dev_getep(&ibuf, &obuf))
        !           360:                return;
1.3       ratchov   361:
                    362:        /*
                    363:         * calculate delta, the number of frames the play chain is ahead
                    364:         * of the record chain. It's necessary to schedule silences (or
                    365:         * drops) in order to start playback and record in sync.
                    366:         */
                    367:        delta =
                    368:            rbuf->bpf * (pbuf->abspos + pbuf->used) -
                    369:            pbuf->bpf *  rbuf->abspos;
                    370:        delta /= pbuf->bpf * rbuf->bpf;
                    371:        DPRINTF("dev_sync: delta = %d, ppos = %u, pused = %u, rpos = %u\n",
                    372:            delta, pbuf->abspos, pbuf->used, rbuf->abspos);
                    373:
                    374:        if (delta > 0) {
                    375:                /*
                    376:                 * if the play chain is ahead (most cases) drop some of
                    377:                 * the recorded input, to get both in sync
                    378:                 */
                    379:                obuf->drop += delta * obuf->bpf;
                    380:                abuf_ipos(obuf, -delta);
                    381:        } else if (delta < 0) {
                    382:                /*
                    383:                 * if record chain is ahead (should never happen,
                    384:                 * right?) then insert silence to play
                    385:                 */
                    386:                ibuf->silence += -delta * ibuf->bpf;
                    387:                abuf_opos(ibuf, delta);
                    388:        } else
                    389:                DPRINTF("dev_sync: nothing to do\n");
1.1       ratchov   390: }
                    391:
                    392: /*
                    393:  * attach the given input and output buffers to the mixer and the
                    394:  * multiplexer respectively. The operation is done synchronously, so
                    395:  * both buffers enter in sync. If buffers do not match play
                    396:  * and rec
                    397:  */
                    398: void
                    399: dev_attach(char *name,
1.10      ratchov   400:     struct abuf *ibuf, struct aparams *sipar, unsigned underrun,
                    401:     struct abuf *obuf, struct aparams *sopar, unsigned overrun)
1.1       ratchov   402: {
                    403:        struct abuf *pbuf = NULL, *rbuf = NULL;
1.12      ratchov   404:        struct aparams ipar, opar;
1.1       ratchov   405:        struct aproc *conv;
1.3       ratchov   406:        unsigned nfr;
1.1       ratchov   407:
                    408:        if (ibuf) {
1.12      ratchov   409:                ipar = *sipar;
1.1       ratchov   410:                pbuf = LIST_FIRST(&dev_mix->obuflist);
1.10      ratchov   411:                if (!aparams_eqenc(&ipar, &dev_opar)) {
1.3       ratchov   412:                        nfr = (dev_bufsz + 3) / 4 + dev_round - 1;
                    413:                        nfr -= nfr % dev_round;
1.10      ratchov   414:                        conv = dec_new(name, &ipar);
                    415:                        ipar.bps = dev_opar.bps;
                    416:                        ipar.bits = dev_opar.bits;
                    417:                        ipar.sig = dev_opar.sig;
                    418:                        ipar.le = dev_opar.le;
                    419:                        ipar.msb = dev_opar.msb;
1.9       ratchov   420:                        aproc_setin(conv, ibuf);
1.10      ratchov   421:                        ibuf = abuf_new(nfr, &ipar);
1.9       ratchov   422:                        aproc_setout(conv, ibuf);
1.8       ratchov   423:                }
1.10      ratchov   424:                if (!aparams_subset(&ipar, &dev_opar)) {
1.7       ratchov   425:                        nfr = (dev_bufsz + 3) / 4 + dev_round - 1;
                    426:                        nfr -= nfr % dev_round;
1.10      ratchov   427:                        conv = cmap_new(name, &ipar, &dev_opar);
                    428:                        ipar.cmin = dev_opar.cmin;
                    429:                        ipar.cmax = dev_opar.cmax;
1.7       ratchov   430:                        aproc_setin(conv, ibuf);
1.10      ratchov   431:                        ibuf = abuf_new(nfr, &ipar);
1.7       ratchov   432:                        aproc_setout(conv, ibuf);
1.6       ratchov   433:                }
1.10      ratchov   434:                if (!aparams_eqrate(&ipar, &dev_opar)) {
1.5       ratchov   435:                        nfr = (dev_bufsz + 3) / 4 + dev_round - 1;
                    436:                        nfr -= nfr % dev_round;
1.10      ratchov   437:                        conv = resamp_new(name, &ipar, &dev_opar);
                    438:                        ipar.rate = dev_opar.rate;
1.5       ratchov   439:                        aproc_setin(conv, ibuf);
1.10      ratchov   440:                        ibuf = abuf_new(nfr, &ipar);
1.5       ratchov   441:                        aproc_setout(conv, ibuf);
1.1       ratchov   442:                }
                    443:                aproc_setin(dev_mix, ibuf);
1.3       ratchov   444:                abuf_opos(ibuf, -dev_mix->u.mix.lat);
1.1       ratchov   445:                ibuf->xrun = underrun;
                    446:        }
                    447:        if (obuf) {
1.12      ratchov   448:                opar = *sopar;
1.1       ratchov   449:                rbuf = LIST_FIRST(&dev_sub->ibuflist);
1.10      ratchov   450:                if (!aparams_eqenc(&opar, &dev_ipar)) {
1.3       ratchov   451:                        nfr = (dev_bufsz + 3) / 4 + dev_round - 1;
                    452:                        nfr -= nfr % dev_round;
1.10      ratchov   453:                        conv = enc_new(name, &opar);
                    454:                        opar.bps = dev_ipar.bps;
                    455:                        opar.bits = dev_ipar.bits;
                    456:                        opar.sig = dev_ipar.sig;
                    457:                        opar.le = dev_ipar.le;
                    458:                        opar.msb = dev_ipar.msb;
1.9       ratchov   459:                        aproc_setout(conv, obuf);
1.10      ratchov   460:                        obuf = abuf_new(nfr, &opar);
1.9       ratchov   461:                        aproc_setin(conv, obuf);
1.8       ratchov   462:                }
1.10      ratchov   463:                if (!aparams_subset(&opar, &dev_ipar)) {
1.7       ratchov   464:                        nfr = (dev_bufsz + 3) / 4 + dev_round - 1;
                    465:                        nfr -= nfr % dev_round;
1.10      ratchov   466:                        conv = cmap_new(name, &dev_ipar, &opar);
                    467:                        opar.cmin = dev_ipar.cmin;
                    468:                        opar.cmax = dev_ipar.cmax;
1.7       ratchov   469:                        aproc_setout(conv, obuf);
1.10      ratchov   470:                        obuf = abuf_new(nfr, &opar);
1.7       ratchov   471:                        aproc_setin(conv, obuf);
1.6       ratchov   472:                }
1.10      ratchov   473:                if (!aparams_eqrate(&opar, &dev_ipar)) {
1.5       ratchov   474:                        nfr = (dev_bufsz + 3) / 4 + dev_round - 1;
                    475:                        nfr -= nfr % dev_round;
1.10      ratchov   476:                        conv = resamp_new(name, &dev_ipar, &opar);
                    477:                        opar.rate = dev_ipar.rate;
1.1       ratchov   478:                        aproc_setout(conv, obuf);
1.10      ratchov   479:                        obuf = abuf_new(nfr, &opar);
1.1       ratchov   480:                        aproc_setin(conv, obuf);
                    481:                }
                    482:                aproc_setout(dev_sub, obuf);
1.3       ratchov   483:                abuf_ipos(obuf, -dev_sub->u.sub.lat);
1.1       ratchov   484:                obuf->xrun = overrun;
                    485:        }
                    486:
                    487:        /*
1.3       ratchov   488:         * sync play to record
1.1       ratchov   489:         */
                    490:        if (ibuf && obuf) {
1.3       ratchov   491:                ibuf->duplex = obuf;
                    492:                obuf->duplex = ibuf;
                    493:                dev_sync(ibuf, obuf);
1.13      ratchov   494:        }
1.14    ! ratchov   495: }
        !           496:
        !           497: /*
        !           498:  * change the playback volume of the fiven stream
        !           499:  */
        !           500: void
        !           501: dev_setvol(struct abuf *ibuf, int vol)
        !           502: {
        !           503:        if (!dev_getep(&ibuf, NULL))
        !           504:                return;
        !           505:        fprintf(stderr, "vol = %d\n", vol);
        !           506:        ibuf->mixvol = vol;
1.13      ratchov   507: }
                    508:
                    509: /*
                    510:  * clear buffers of the play and record chains so that when the device
                    511:  * is started, playback and record start in sync
                    512:  */
                    513: void
                    514: dev_clear(void)
                    515: {
                    516:        struct abuf *buf;
                    517:
                    518:        if (dev_mix) {
                    519:                if (!LIST_EMPTY(&dev_mix->ibuflist)) {
                    520:                        fprintf(stderr, "dev_clear: mixer not idle\n");
                    521:                        abort();
                    522:                }
                    523:                buf = LIST_FIRST(&dev_mix->obuflist);
                    524:                while (buf) {
                    525:                        abuf_clear(buf);
                    526:                        buf = LIST_FIRST(&buf->rproc->obuflist);
                    527:                }
                    528:                mix_clear(dev_mix);
                    529:        }
                    530:        if (dev_sub) {
                    531:                if (!LIST_EMPTY(&dev_sub->obuflist)) {
                    532:                        fprintf(stderr, "dev_suspend: demux not idle\n");
                    533:                        abort();
                    534:                }
                    535:                buf = LIST_FIRST(&dev_sub->ibuflist);
                    536:                while (buf) {
                    537:                        abuf_clear(buf);
                    538:                        buf = LIST_FIRST(&buf->wproc->ibuflist);
                    539:                }
                    540:                sub_clear(dev_sub);
1.1       ratchov   541:        }
                    542: }